§ 01

§ 01 · Bytes & numbers

Hexadecimal

Counting in sixteens, two characters per byte

Hexadecimal (“hex”) is a way of writing numbers with sixteen digits instead of ten.

You’ll see it everywhere in Pearl. Every key, hash, signature and raw transaction on this site is written in hex. That’s not because the numbers are special. It’s because hex is the tidiest way to write down bytes.

Try it

Type a number in any box. Watch it change between decimal, hex and binary.

Hex converter

Decimal, hex and binary, and the bytes in both orders

Big-endian as written
0001ff0b
Little-endian as stored
0bff0100
Runs in your browser · nothing is sent src/lib/bytes.ts

What are the sixteen digits?

Normal counting (decimal) has ten digits, 0 to 9. When you run out, you carry one into the next column: 9, then 10.

Hex has six more digits before it carries. It borrows letters for them:

Decimal 0–9 10 11 12 13 14 15 16
Hex 0–9 a b c d e f 10

So in hex, “10” means sixteen, not ten. To avoid confusion, hex numbers are often written with a 0x in front: 0x10 is sixteen.

Capital and small letters mean the same thing. Pearl’s software prints small letters.

Why does every byte take two characters?

Because sixteen is a power of two.

One hex digit has 16 possible values, which is exactly what four bits can hold (2 × 2 × 2 × 2 = 16). Half a byte, four bits, is sometimes called a nibble. Two nibbles make a byte, so one byte is always exactly two hex characters, from 00 to ff.

decimal 194c21100001012 = 8 + 42
One byte, three ways. Each hex digit stands for exactly four bits, so you can convert between hex and binary one digit at a time.

This is the whole reason hex is used. Binary is too long to read (a hash is 256 ones and zeros). Decimal hides where one byte ends and the next begins. Hex is short and keeps the bytes visible: every pair of characters is one byte.

How do you convert hex to decimal?

Each column is worth sixteen times the one to its right, just as each decimal column is worth ten times more.

𝟶𝚡𝚌𝟸=12×16+2=194\texttt{0xc2} = 12 \times 16 + 2 = 194
Hex to decimal

For a longer number, keep going with 256, 4,096, 65,536 and so on. Pearl’s coin type, the number in every wallet’s derivation path, is 808,276. In hex it is 0xc5554:

𝟶𝚡𝚌𝟻𝟻𝟻𝟺=12⋅164+5⋅163+5⋅162+5⋅16+4=808,276\texttt{0xc5554} = 12 \cdot 16^4 + 5 \cdot 16^3 + 5 \cdot 16^2 + 5 \cdot 16 + 4 = 808{,}276
Going the other way: decimal to hex

Divide by 16 and write down the remainder. Repeat with the quotient until it reaches zero. The remainders, read from last to first, are the hex digits.

Step Divide Quotient Remainder
1 194 ÷ 16 12 2
2 12 ÷ 16 0 12 = c

Reading the remainders upwards gives c2. The same method turns block height 130,825 into 0x1ff09.

Where do you see hex in Pearl?

Almost everywhere data is shown rather than spoken:

  • Hashes. A block hash like 3fc851763893a0135ea756d5dcbe355f375e613957930e7f401fafc8ee5533ae is 32 bytes, so 64 characters.
  • Raw data. A 108-byte Pearl header is 216 hex characters. A raw transaction is its bytes in hex, start to finish.
  • Keys and signatures. A private key is 64 characters, an x-only public key 64, a Schnorr signature 128.
  • Constants in the code. Pearl’s difficulty-1 bits are 0x1b00ffff, the XMSS opcode is 0xde, and the mainnet network magic is 0x50524C4D, which spells “PRLM” in ASCII.

Make a guess

Block 130,825's coinbase starts its script with the bytes 03 09 ff 01. The last three bytes hold the block height. 0x1ff09 is 130,825, but the bytes say 09 ff 01. Why are they in that order?

Think of your answer first, then check it.

Answer The bytes are little-endian: smallest byte first.

Read backwards, 09 ff 01 becomes 01 ff 09, which is 0x1ff09 = 130,825. Hex shows you the bytes faithfully, in the order they are stored. Whether you read them forwards or backwards is a separate question, answered on the byte order page.

How do you find one byte in a long hex string?

Count in pairs. Byte number n (counting from 0) starts at character 2n, and every field is twice as many characters as it is bytes.

Take block 130,825’s header, 216 characters long. Its bits field is bytes 72 to 75, so it sits at characters 144 to 151: ebd06a17. Its Merkle root is bytes 36 to 67, characters 72 to 135.

Pearl’s code, explorers and this site always give offsets in bytes, not characters. When a page says “offset 76”, double it to find the spot in the hex.

Block 130,825 · header 108 bytes
00000020 d3221e43dc59c5d0dae1ee53987d6a4abeef42567d682017a6edd6e0de7ac7ab 2a051d25484d57e49a1f3b757685403ed06f558bb06a1804c34fac74ee7f5fab 8393d76a ebd06a17 ce6de312e0e4ca6c862c05835314db00cf02c13a20ea4810940f09b64ed8ba86
Field Bytes Value
Version header.version 4 @0 0x20000000 int32 LE. BIP-9 style 0x20000000 since block 1; no consensus meaning in Pearl.
Previous block header.prevBlock 32 @4 abc77adee0d6eda61720687d5642efbe4a6a7d9853eee1dad0c559dc431e22d3 Hash of the parent block, stored byte-reversed; shown in display order.
Merkle root header.merkleRoot 32 @36 ab5f7fee74ac4fc304186ab08b556fd03e408576753b1f9ae4574d48251d052a Root of the SHA256d Merkle tree of this block’s txids, stored byte-reversed.
Time header.timestamp 4 @68 1792512899 (2026-10-20 16:14:59 UTC) uint32 LE Unix seconds. Must be at least 1 s after the parent and at most 5 min in the future.
Bits header.bits 4 @72 0x176ad0eb Compact target. Difficulty 40208379.91968057. The certificate's jackpot hash (not this header's hash) must meet it.
Proof commitment header.proofCommitment 32 @76 86bad84eb6090f941048ea203ac102cf00db145383052c866ccae4e012e36dce SHA256d(LE32(certificate version) ‖ public data). Replaces Bitcoin’s nonce: Pearl headers have no nonce.
Block hash
3fc851763893a0135ea756d5dcbe355f375e613957930e7f401fafc8ee5533ae
Height
130,825
Time
2026-10-20 16:14:59 UTC
Difficulty
40,208,379.92

Is hex a different kind of number?

No. Hex is only a way of writing a number, like Roman numerals. 0xc2, 194 and 11000010 are the same value, stored as the same eight bits.

That matters when you hash things. Hashing the text “c2” (two characters, two bytes) is not the same as hashing the byte 0xc2 (one byte). Tools on this site always say which one they mean.

Code: hex in Pearl's source and in JavaScript

pearld prints a hash by reversing its 32 bytes and hex-encoding them, in Hash.String() (node/chaincfg/chainhash/hash.go:73-80 at v1.5.2, on GitHub):

node/chaincfg/chainhash/hash.go Go
// String returns the Hash as the hexadecimal string of the byte-reversed
// hash.
func (hash Hash) String() string {
	for i := 0; i < HashSize/2; i++ {
		hash[i], hash[HashSize-1-i] = hash[HashSize-1-i], hash[i]
	}
	return hex.EncodeToString(hash[:])
}

In a browser:

JavaScript
(194).toString(16);          // 'c2'
parseInt('c5554', 16);       // 808276
const hex = (bytes) => [...bytes].map((b) => b.toString(16).padStart(2, '0')).join('');

The codex

Suggested

Up and down arrows move through the results, Enter opens one, Escape closes. Anywhere on the site, slash or Command K opens this search, and the square brackets [ and ] go to the previous and next page.