alice pellerin • 2026-03-31
too often, i see hex editors1 that look like this:
00000000 00 00 02 00 28 00 00 00 88 15 00 00 C4 01 00 00 ⋄⋄•⋄(⋄⋄⋄ו⋄⋄ו⋄⋄
00000010 14 00 00 00 03 00 00 00 00 01 00 00 03 00 00 00 •⋄⋄⋄•⋄⋄⋄⋄•⋄⋄•⋄⋄⋄
00000020 3C 00 00 00 C4 0A 00 00 50 00 00 00 18 00 00 00 <⋄⋄⋄×⏎⋄⋄P⋄⋄⋄•⋄⋄⋄
00000030 14 00 00 10 00 00 00 00 18 00 00 20 00 00 00 00 •⋄⋄•⋄⋄⋄⋄•⋄⋄ ⋄⋄⋄⋄
00000040 20 00 00 30 00 00 00 00 51 00 00 00 48 00 00 00 ⋄⋄0⋄⋄⋄⋄Q⋄⋄⋄H⋄⋄⋄
00000050 10 00 00 80 00 00 00 00 00 00 00 A0 00 00 00 00 •⋄⋄×⋄⋄⋄⋄⋄⋄⋄×⋄⋄⋄⋄
00000060 01 00 00 A0 01 00 00 00 02 00 00 A0 02 00 00 00 •⋄⋄ו⋄⋄⋄•⋄⋄ו⋄⋄⋄
00000070 03 00 00 A0 03 00 00 00 04 00 00 A0 04 00 00 00 •⋄⋄ו⋄⋄⋄•⋄⋄ו⋄⋄⋄
00000080 05 00 00 A0 05 00 00 00 06 00 00 A0 06 00 00 00 •⋄⋄ו⋄⋄⋄•⋄⋄ו⋄⋄⋄
00000090 20 00 00 30 00 00 00 00 53 00 00 00 00 DE 00 00 ⋄⋄0⋄⋄⋄⋄S⋄⋄⋄⋄×⋄⋄
000000a0 5D FA 01 44 E1 3A 9A 0F 52 00 00 00 FC 14 00 00 ]וD×:וR⋄⋄⋄ו⋄⋄
000000b0 1B 20 2A 2B 00 80 00 00 00 80 00 00 00 80 00 00 • *+⋄×⋄⋄⋄×⋄⋄⋄×⋄⋄
000000c0 FF 7F 00 00 00 00 33 52 00 00 00 00 29 10 15 10 ╳•⋄⋄⋄⋄3R⋄⋄⋄⋄)•••
000000d0 80 00 1F 00 03 00 00 00 02 00 00 00 40 14 22 23 ×⋄•⋄•⋄⋄⋄•⋄⋄⋄@•"#
000000e0 03 00 00 00 06 00 00 00 23 00 9D 05 6B FA C0 05 •⋄⋄⋄•⋄⋄⋄#⋄וk×ו
000000f0 C8 03 00 00 14 22 23 14 05 00 00 00 2E 00 9E 06 ו⋄⋄•"#••⋄⋄⋄.⋄וevery time i do, i feel bad for the poor person having to use it (especially if that person is me!). a plain list of bytes makes it hard to notice interesting things in the data. go ahead, try to find the single C0 in these bytes:
00000000 15 29 21 25 03 2F 2E 2B 15 11 24 3F 10 14 3B 13 •)!%•/.+••$?••;•
00000001 32 25 09 01 10 02 01 23 26 1E 25 2D 24 2F 23 3E 2%␣••••#&•%-$/#>
00000002 05 0F 33 2D 18 29 3E 1E 16 3B 29 0D 24 0B 3E 38 ••3-•)>••;)␍$•>8
00000003 33 3C 1E 2C 28 31 C0 1D 11 32 14 05 10 17 3F 01 3<•,(1ו•2••••?•
00000004 1E 32 0A 14 2B 2F 0B 14 3E 27 39 0A 17 23 1B 39 •2⏎•+/••>'9⏎•#•9
00000005 18 0B 3B 13 25 14 2C 3B 33 3C 19 10 21 0F 2C 34 ••;•%•,;3<••!•,4
00000006 2F 0C 1D 2C 2E 22 11 28 0D 0A 1F 37 27 39 35 21 /••,."•(␍⏎•7'95!
00000007 23 39 21 2B 37 23 28 16 30 28 02 04 25 22 37 1F #9!+7#(•0(••%"7•
00000008 36 2F 2D 25 12 25 01 31 3B 39 2D 35 26 37 30 2A 6/-%•%•1;9-5&70*
00000009 06 0D 11 1F 25 0A 1E 29 15 0B 0A 2A 2E 2C 21 16 •␍••%⏎•)••⏎*.,!•
0000000a 1D 37 0F 16 12 03 2C 02 0B 22 24 11 1A 3B 0D 0B •7••••,••"$••;␍•
0000000b 0D 13 30 2D 3B 15 05 15 32 19 20 30 3C 0E 3D 0B ␍•0-;•••2• 0<•=•
0000000c 17 24 22 3E 1E 22 18 0D 21 06 29 38 3E 20 3B 12 •$">•"•␍!•)8> ;•
0000000d 06 1F 19 17 29 35 1E 3B 1E 01 31 08 13 0C 27 20 ••••)5•;••1•••'
0000000e 08 24 2E 32 16 06 1F 3D 35 35 19 16 02 07 31 13 •$.2•••=55••••1•
0000000f 31 33 30 36 14 32 07 05 05 34 19 0B 18 16 12 3C 1306•2•••4•••••<compare that to one with colors:
00000000 37 2D 08 13 0D 0B 18 1D 02 1A 2D 12 2A 0D 0F 27 7-••␍•••••-•*␍•'
00000001 04 2A 25 32 0F 17 32 11 2F 2A 2A 0A 0A 16 04 1D •*%2••2•/**⏎⏎•••
00000002 32 13 09 01 2B 26 1A 30 3D 26 13 39 09 0D 38 3E 2•␣•+&•0=&•9␣␍8>
00000003 0A 0D 1D 0B 36 30 02 36 0E 0B 2F 09 26 1E 33 03 ⏎␍••60•6••/␣&•3•
00000004 3C 3C 08 0A 1E 36 12 11 1B 17 05 09 0B 37 0C 0E <<•⏎•6•••••␣•7••
00000005 31 05 09 17 2D 1D 05 16 25 03 3E 0A 1A 01 0C 2B 1•␣•-•••%•>⏎•••+
00000006 13 37 17 14 37 03 18 34 2D 03 30 11 2B 19 04 0B •7••7••4-•0•+•••
00000007 04 2A 18 26 21 25 3F 23 1D 0F 2F 2B 35 0C 09 37 •*•&!%?#••/+5•␣7
00000008 25 33 19 1C 12 1E 2E 38 3A 3A 3C 28 39 0A 30 23 %3••••.8::<(9⏎0#
00000009 21 08 09 24 0B 0E 13 26 04 30 06 20 10 18 15 3C !•␣$•••&•0• •••<
0000000a 10 3C 30 34 28 28 1D 31 22 23 22 38 0E 12 25 15 •<04((•1"#"8••%•
0000000b 3B 1F 30 0D 26 0E 15 32 1C 2B 12 1A 32 1C 02 07 ;•0␍&••2•+••2•••
0000000c 35 2E 06 13 1F 33 3D 16 05 1C 2A 0F 34 34 21 26 5.•••3=•••*•44!&
0000000d 0C 17 3D 02 27 39 21 17 3F 07 1A 2F 38 0D 2D 1E ••=•'9!•?••/8␍-•
0000000e 32 0C C0 14 0E 20 25 0E 2E 2D 0D 21 27 13 2C 07 2•ו• %•.-␍!'•,•
0000000f 14 0A 20 31 15 13 2C 3B 0F 12 1A 2D 0C 11 32 11 •⏎ 1••,;•••-••2•it’s much easier to pick out the unique byte when it’s a different color! human brains are really good at spotting visual patterns—given the right format
here are a few more examples:
00000000 4B 50 53 00 0A 00 00 00 0C 00 00 00 01 00 00 00 KPS⋄⏎⋄⋄⋄•⋄⋄⋄•⋄⋄⋄
00000010 00 00 00 00 B4 00 00 00 46 00 00 00 64 00 00 00 ⋄⋄⋄⋄×⋄⋄⋄F⋄⋄⋄d⋄⋄⋄
00000020 46 00 00 00 02 00 00 00 00 00 00 00 DC 00 00 00 F⋄⋄⋄•⋄⋄⋄⋄⋄⋄⋄×⋄⋄⋄
00000030 50 00 00 00 A0 00 00 00 50 00 00 00 03 00 00 00 P⋄⋄⋄×⋄⋄⋄P⋄⋄⋄•⋄⋄⋄
00000040 00 00 00 00 FA 00 00 00 5A 00 00 00 B4 00 00 00 ⋄⋄⋄⋄×⋄⋄⋄Z⋄⋄⋄×⋄⋄⋄
00000050 5A 00 00 00 04 00 00 00 00 00 00 00 18 01 00 00 Z⋄⋄⋄•⋄⋄⋄⋄⋄⋄⋄••⋄⋄
00000060 64 00 00 00 C8 00 00 00 64 00 00 00 05 00 00 00 d⋄⋄⋄×⋄⋄⋄d⋄⋄⋄•⋄⋄⋄
00000070 00 00 00 00 4A 01 00 00 78 00 00 00 F0 00 00 00 ⋄⋄⋄⋄J•⋄⋄x⋄⋄⋄×⋄⋄⋄
00000080 78 00 00 00 06 00 00 00 00 00 00 00 90 01 00 00 x⋄⋄⋄•⋄⋄⋄⋄⋄⋄⋄ו⋄⋄
00000090 8C 00 00 00 18 01 00 00 8C 00 00 00 07 00 00 00 ×⋄⋄⋄••⋄⋄×⋄⋄⋄•⋄⋄⋄
000000a0 00 00 00 00 F4 01 00 00 B4 00 00 00 68 01 00 00 ⋄⋄⋄⋄ו⋄⋄×⋄⋄⋄h•⋄⋄
000000b0 B4 00 00 00 08 00 00 00 00 00 00 00 58 02 00 00 ×⋄⋄⋄•⋄⋄⋄⋄⋄⋄⋄X•⋄⋄
000000c0 DC 00 00 00 B8 01 00 00 DC 00 00 00 09 00 00 00 ×⋄⋄⋄ו⋄⋄×⋄⋄⋄␣⋄⋄⋄
000000d0 E7 03 00 00 E7 03 00 00 00 00 00 00 E7 03 00 00 ו⋄⋄ו⋄⋄⋄⋄⋄⋄ו⋄⋄
000000e0 E7 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ו⋄⋄⋄⋄⋄⋄⋄⋄⋄⋄⋄⋄⋄⋄
000000f0 00 00 00 00 00 00 00 00 00 00 00 00 ⋄⋄⋄⋄⋄⋄⋄⋄⋄⋄⋄⋄00000000 4B 50 53 00 0A 00 00 00 0C 00 00 00 01 00 00 00 KPS⋄⏎⋄⋄⋄•⋄⋄⋄•⋄⋄⋄
00000010 00 00 00 00 B4 00 00 00 46 00 00 00 64 00 00 00 ⋄⋄⋄⋄×⋄⋄⋄F⋄⋄⋄d⋄⋄⋄
00000020 46 00 00 00 02 00 00 00 00 00 00 00 DC 00 00 00 F⋄⋄⋄•⋄⋄⋄⋄⋄⋄⋄×⋄⋄⋄
00000030 50 00 00 00 A0 00 00 00 50 00 00 00 03 00 00 00 P⋄⋄⋄×⋄⋄⋄P⋄⋄⋄•⋄⋄⋄
00000040 00 00 00 00 FA 00 00 00 5A 00 00 00 B4 00 00 00 ⋄⋄⋄⋄×⋄⋄⋄Z⋄⋄⋄×⋄⋄⋄
00000050 5A 00 00 00 04 00 00 00 00 00 00 00 18 01 00 00 Z⋄⋄⋄•⋄⋄⋄⋄⋄⋄⋄••⋄⋄
00000060 64 00 00 00 C8 00 00 00 64 00 00 00 05 00 00 00 d⋄⋄⋄×⋄⋄⋄d⋄⋄⋄•⋄⋄⋄
00000070 00 00 00 00 4A 01 00 00 78 00 00 00 F0 00 00 00 ⋄⋄⋄⋄J•⋄⋄x⋄⋄⋄×⋄⋄⋄
00000080 78 00 00 00 06 00 00 00 00 00 00 00 90 01 00 00 x⋄⋄⋄•⋄⋄⋄⋄⋄⋄⋄ו⋄⋄
00000090 8C 00 00 00 18 01 00 00 8C 00 00 00 07 00 00 00 ×⋄⋄⋄••⋄⋄×⋄⋄⋄•⋄⋄⋄
000000a0 00 00 00 00 F4 01 00 00 B4 00 00 00 68 01 00 00 ⋄⋄⋄⋄ו⋄⋄×⋄⋄⋄h•⋄⋄
000000b0 B4 00 00 00 08 00 00 00 00 00 00 00 58 02 00 00 ×⋄⋄⋄•⋄⋄⋄⋄⋄⋄⋄X•⋄⋄
000000c0 DC 00 00 00 B8 01 00 00 DC 00 00 00 09 00 00 00 ×⋄⋄⋄ו⋄⋄×⋄⋄⋄␣⋄⋄⋄
000000d0 E7 03 00 00 E7 03 00 00 00 00 00 00 E7 03 00 00 ו⋄⋄ו⋄⋄⋄⋄⋄⋄ו⋄⋄
000000e0 E7 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ו⋄⋄⋄⋄⋄⋄⋄⋄⋄⋄⋄⋄⋄⋄
000000f0 00 00 00 00 00 00 00 00 00 00 00 00 ⋄⋄⋄⋄⋄⋄⋄⋄⋄⋄⋄⋄this file starts with the magic bytes KPS, then a bunch of (little-endian) 32-bit integers that range from 0 to 999 (0x3E7). the colors make it quick to recognize that every 32-bit integer is relatively small, as the two high bytes are always . if you look closely, you may notice other patterns, like the numbers counting up every 0x18 bytes starting at 0xC
if you're curious about this particular file format, the code that parses it is pretty simple, even if you're not a programmer. there's even a wiki page for the data it represents, if you're into Fossil Fighters
00000000 44 41 4C 00 59 06 00 00 F4 07 00 00 F5 01 00 00 DAL⋄Y•⋄⋄ו⋄⋄ו⋄⋄
00000010 14 00 00 00 E8 07 00 00 08 08 00 00 44 08 00 00 •⋄⋄⋄ו⋄⋄••⋄⋄D•⋄⋄
00000020 84 08 00 00 C8 08 00 00 04 09 00 00 40 09 00 00 ו⋄⋄ו⋄⋄•␣⋄⋄@␣⋄⋄
00000030 7C 09 00 00 B8 09 00 00 F8 09 00 00 34 0A 00 00 |␣⋄⋄×␣⋄⋄×␣⋄⋄4⏎⋄⋄
00000040 70 0A 00 00 AC 0A 00 00 EC 0A 00 00 30 0B 00 00 p⏎⋄⋄×⏎⋄⋄×⏎⋄⋄0•⋄⋄
00000050 6C 0B 00 00 A8 0B 00 00 E8 0B 00 00 24 0C 00 00 l•⋄⋄ו⋄⋄ו⋄⋄$•⋄⋄
00000060 60 0C 00 00 9C 0C 00 00 D8 0C 00 00 14 0D 00 00 `•⋄⋄ו⋄⋄ו⋄⋄•␍⋄⋄
00000070 50 0D 00 00 8C 0D 00 00 CC 0D 00 00 08 0E 00 00 P␍⋄⋄×␍⋄⋄×␍⋄⋄••⋄⋄
00000080 48 0E 00 00 84 0E 00 00 C4 0E 00 00 08 0F 00 00 H•⋄⋄ו⋄⋄ו⋄⋄••⋄⋄
00000090 44 0F 00 00 80 0F 00 00 C0 0F 00 00 04 10 00 00 D•⋄⋄ו⋄⋄ו⋄⋄••⋄⋄
000000a0 40 10 00 00 80 10 00 00 C4 10 00 00 00 11 00 00 @•⋄⋄ו⋄⋄ו⋄⋄⋄•⋄⋄
000000b0 3C 11 00 00 7C 11 00 00 B8 11 00 00 F4 11 00 00 <•⋄⋄|•⋄⋄ו⋄⋄ו⋄⋄
000000c0 34 12 00 00 70 12 00 00 B0 12 00 00 F4 12 00 00 4•⋄⋄p•⋄⋄ו⋄⋄ו⋄⋄
000000d0 30 13 00 00 70 13 00 00 B4 13 00 00 F0 13 00 00 0•⋄⋄p•⋄⋄ו⋄⋄ו⋄⋄
000000e0 2C 14 00 00 68 14 00 00 A4 14 00 00 E4 14 00 00 ,•⋄⋄h•⋄⋄ו⋄⋄ו⋄⋄
000000f0 20 15 00 00 5C 15 00 00 9C 15 00 00 E0 15 00 00 •⋄⋄\•⋄⋄ו⋄⋄ו⋄⋄
00000100 1C 16 00 00 58 16 00 00 98 16 00 00 DC 16 00 00 ••⋄⋄X•⋄⋄ו⋄⋄ו⋄⋄
00000110 18 17 00 00 58 17 00 00 9C 17 00 00 D8 17 00 00 ••⋄⋄X•⋄⋄ו⋄⋄ו⋄⋄
00000120 14 18 00 00 54 18 00 00 90 18 00 00 D0 18 00 00 ••⋄⋄T•⋄⋄ו⋄⋄ו⋄⋄
00000130 14 19 00 00 50 19 00 00 8C 19 00 00 C8 19 00 00 ••⋄⋄P•⋄⋄ו⋄⋄ו⋄⋄
00000140 04 1A 00 00 40 1A 00 00 7C 1A 00 00 B8 1A 00 00 ••⋄⋄@•⋄⋄|•⋄⋄ו⋄⋄
00000150 F4 1A 00 00 30 1B 00 00 6C 1B 00 00 AC 1B 00 00 ו⋄⋄0•⋄⋄l•⋄⋄ו⋄⋄
00000160 F0 1B 00 00 2C 1C 00 00 68 1C 00 00 A8 1C 00 00 ו⋄⋄,•⋄⋄h•⋄⋄ו⋄⋄
00000170 EC 1C 00 00 28 1D 00 00 68 1D 00 00 AC 1D 00 00 ו⋄⋄(•⋄⋄h•⋄⋄ו⋄⋄
00000180 E8 1D 00 00 28 1E 00 00 6C 1E 00 00 A8 1E 00 00 ו⋄⋄(•⋄⋄l•⋄⋄ו⋄⋄
00000190 E8 1E 00 00 2C 1F 00 00 68 1F 00 00 A8 1F 00 00 ו⋄⋄,•⋄⋄h•⋄⋄ו⋄⋄
000001a0 EC 1F 00 00 28 20 00 00 68 20 00 00 AC 20 00 00 ו⋄⋄( ⋄⋄h ⋄⋄× ⋄⋄
000001b0 E8 20 00 00 30 21 00 00 6C 21 00 00 A8 21 00 00 × ⋄⋄0!⋄⋄l!⋄⋄×!⋄⋄
000001c0 E4 21 00 00 24 22 00 00 68 22 00 00 A4 22 00 00 ×!⋄⋄$"⋄⋄h"⋄⋄×"⋄⋄
000001d0 E0 22 00 00 1C 23 00 00 5C 23 00 00 A0 23 00 00 ×"⋄⋄•#⋄⋄\#⋄⋄×#⋄⋄
000001e0 DC 23 00 00 18 24 00 00 58 24 00 00 9C 24 00 00 ×#⋄⋄•$⋄⋄X$⋄⋄×$⋄⋄
000001f0 D8 24 00 00 18 25 00 00 54 25 00 00 94 25 00 00 ×$⋄⋄•%⋄⋄T%⋄⋄×%⋄⋄
00000200 D8 25 00 00 14 26 00 00 54 26 00 00 90 26 00 00 ×%⋄⋄•&⋄⋄T&⋄⋄×&⋄⋄
...00000000 44 41 4C 00 59 06 00 00 F4 07 00 00 F5 01 00 00 DAL⋄Y•⋄⋄ו⋄⋄ו⋄⋄
00000010 14 00 00 00 E8 07 00 00 08 08 00 00 44 08 00 00 •⋄⋄⋄ו⋄⋄••⋄⋄D•⋄⋄
00000020 84 08 00 00 C8 08 00 00 04 09 00 00 40 09 00 00 ו⋄⋄ו⋄⋄•␣⋄⋄@␣⋄⋄
00000030 7C 09 00 00 B8 09 00 00 F8 09 00 00 34 0A 00 00 |␣⋄⋄×␣⋄⋄×␣⋄⋄4⏎⋄⋄
00000040 70 0A 00 00 AC 0A 00 00 EC 0A 00 00 30 0B 00 00 p⏎⋄⋄×⏎⋄⋄×⏎⋄⋄0•⋄⋄
00000050 6C 0B 00 00 A8 0B 00 00 E8 0B 00 00 24 0C 00 00 l•⋄⋄ו⋄⋄ו⋄⋄$•⋄⋄
00000060 60 0C 00 00 9C 0C 00 00 D8 0C 00 00 14 0D 00 00 `•⋄⋄ו⋄⋄ו⋄⋄•␍⋄⋄
00000070 50 0D 00 00 8C 0D 00 00 CC 0D 00 00 08 0E 00 00 P␍⋄⋄×␍⋄⋄×␍⋄⋄••⋄⋄
00000080 48 0E 00 00 84 0E 00 00 C4 0E 00 00 08 0F 00 00 H•⋄⋄ו⋄⋄ו⋄⋄••⋄⋄
00000090 44 0F 00 00 80 0F 00 00 C0 0F 00 00 04 10 00 00 D•⋄⋄ו⋄⋄ו⋄⋄••⋄⋄
000000a0 40 10 00 00 80 10 00 00 C4 10 00 00 00 11 00 00 @•⋄⋄ו⋄⋄ו⋄⋄⋄•⋄⋄
000000b0 3C 11 00 00 7C 11 00 00 B8 11 00 00 F4 11 00 00 <•⋄⋄|•⋄⋄ו⋄⋄ו⋄⋄
000000c0 34 12 00 00 70 12 00 00 B0 12 00 00 F4 12 00 00 4•⋄⋄p•⋄⋄ו⋄⋄ו⋄⋄
000000d0 30 13 00 00 70 13 00 00 B4 13 00 00 F0 13 00 00 0•⋄⋄p•⋄⋄ו⋄⋄ו⋄⋄
000000e0 2C 14 00 00 68 14 00 00 A4 14 00 00 E4 14 00 00 ,•⋄⋄h•⋄⋄ו⋄⋄ו⋄⋄
000000f0 20 15 00 00 5C 15 00 00 9C 15 00 00 E0 15 00 00 •⋄⋄\•⋄⋄ו⋄⋄ו⋄⋄
00000100 1C 16 00 00 58 16 00 00 98 16 00 00 DC 16 00 00 ••⋄⋄X•⋄⋄ו⋄⋄ו⋄⋄
00000110 18 17 00 00 58 17 00 00 9C 17 00 00 D8 17 00 00 ••⋄⋄X•⋄⋄ו⋄⋄ו⋄⋄
00000120 14 18 00 00 54 18 00 00 90 18 00 00 D0 18 00 00 ••⋄⋄T•⋄⋄ו⋄⋄ו⋄⋄
00000130 14 19 00 00 50 19 00 00 8C 19 00 00 C8 19 00 00 ••⋄⋄P•⋄⋄ו⋄⋄ו⋄⋄
00000140 04 1A 00 00 40 1A 00 00 7C 1A 00 00 B8 1A 00 00 ••⋄⋄@•⋄⋄|•⋄⋄ו⋄⋄
00000150 F4 1A 00 00 30 1B 00 00 6C 1B 00 00 AC 1B 00 00 ו⋄⋄0•⋄⋄l•⋄⋄ו⋄⋄
00000160 F0 1B 00 00 2C 1C 00 00 68 1C 00 00 A8 1C 00 00 ו⋄⋄,•⋄⋄h•⋄⋄ו⋄⋄
00000170 EC 1C 00 00 28 1D 00 00 68 1D 00 00 AC 1D 00 00 ו⋄⋄(•⋄⋄h•⋄⋄ו⋄⋄
00000180 E8 1D 00 00 28 1E 00 00 6C 1E 00 00 A8 1E 00 00 ו⋄⋄(•⋄⋄l•⋄⋄ו⋄⋄
00000190 E8 1E 00 00 2C 1F 00 00 68 1F 00 00 A8 1F 00 00 ו⋄⋄,•⋄⋄h•⋄⋄ו⋄⋄
000001a0 EC 1F 00 00 28 20 00 00 68 20 00 00 AC 20 00 00 ו⋄⋄( ⋄⋄h ⋄⋄× ⋄⋄
000001b0 E8 20 00 00 30 21 00 00 6C 21 00 00 A8 21 00 00 × ⋄⋄0!⋄⋄l!⋄⋄×!⋄⋄
000001c0 E4 21 00 00 24 22 00 00 68 22 00 00 A4 22 00 00 ×!⋄⋄$"⋄⋄h"⋄⋄×"⋄⋄
000001d0 E0 22 00 00 1C 23 00 00 5C 23 00 00 A0 23 00 00 ×"⋄⋄•#⋄⋄\#⋄⋄×#⋄⋄
000001e0 DC 23 00 00 18 24 00 00 58 24 00 00 9C 24 00 00 ×#⋄⋄•$⋄⋄X$⋄⋄×$⋄⋄
000001f0 D8 24 00 00 18 25 00 00 54 25 00 00 94 25 00 00 ×$⋄⋄•%⋄⋄T%⋄⋄×%⋄⋄
00000200 D8 25 00 00 14 26 00 00 54 26 00 00 90 26 00 00 ×%⋄⋄•&⋄⋄T&⋄⋄×&⋄⋄
...this excerpt, starting at 0x14, has a long series of increasing 32-bit integers (little-endian again). each one is an index to a later point in the file, to a structure usually about 0x3C bytes long. the roughly-evenly-spaced indices make for some very pretty rainbow gradients
...
00000030 0F 80 00 00 00 01 C1 82 82 83 01 05 04 82 03 82 •×⋄⋄⋄•×××ו••ו×
00000040 0F 82 07 C2 0C C2 0B 82 0A 0D 08 02 09 C0 0E 06 •ווו×⏎␍••␣ו•
00000050 56 05 E8 43 01 64 52 F5 A4 8D A1 33 D5 98 BF C6 V•×C•dR××××3××××
00000060 63 EB 4C 8C C6 C3 F8 1A 6A 2A 46 2B C5 F8 15 F3 c×L×××וj*F+×ו×
00000070 60 42 8A 71 E6 56 0C 2A D5 4C 0C 2B 5F 31 A9 18 `B×q×V•*×L•+_1ו
00000080 4C 8C 55 CC 5B 30 C6 D6 18 37 86 7D BB C3 8F CD L×U×[0×ו7×}××××
00000090 1E B9 BB BB 91 FA 22 23 9E 71 7A 8B 35 6F F3 84 •×××××"#×qz×5o××
000000a0 38 DE B7 C9 58 76 A4 9C D7 C5 F8 63 CF A2 B4 BE 8×××Xv×××××c××××
000000b0 B2 45 BC 8D F7 6A 35 EF E2 B9 CD A7 46 F7 F9 AD ×E×××j5×××××F×××
000000c0 7F 6F D7 BC 72 DD DB 9D 6B DE 8F EE C6 35 EF B7 •o××r×××k××××5××
000000d0 AE 6B E4 9A AE E9 9B 6B AF 23 8E 66 B0 2D 22 47 ×k×××××k×#×f×-"G...
00000030 0F 80 00 00 00 01 C1 82 82 83 01 05 04 82 03 82 •×⋄⋄⋄•×××ו••ו×
00000040 0F 82 07 C2 0C C2 0B 82 0A 0D 08 02 09 C0 0E 06 •ווו×⏎␍••␣ו•
00000050 56 05 E8 43 01 64 52 F5 A4 8D A1 33 D5 98 BF C6 V•×C•dR××××3××××
00000060 63 EB 4C 8C C6 C3 F8 1A 6A 2A 46 2B C5 F8 15 F3 c×L×××וj*F+×ו×
00000070 60 42 8A 71 E6 56 0C 2A D5 4C 0C 2B 5F 31 A9 18 `B×q×V•*×L•+_1ו
00000080 4C 8C 55 CC 5B 30 C6 D6 18 37 86 7D BB C3 8F CD L×U×[0×ו7×}××××
00000090 1E B9 BB BB 91 FA 22 23 9E 71 7A 8B 35 6F F3 84 •×××××"#×qz×5o××
000000a0 38 DE B7 C9 58 76 A4 9C D7 C5 F8 63 CF A2 B4 BE 8×××Xv×××××c××××
000000b0 B2 45 BC 8D F7 6A 35 EF E2 B9 CD A7 46 F7 F9 AD ×E×××j5×××××F×××
000000c0 7F 6F D7 BC 72 DD DB 9D 6B DE 8F EE C6 35 EF B7 •o××r×××k××××5××
000000d0 AE 6B E4 9A AE E9 9B 6B AF 23 8E 66 B0 2D 22 47 ×k×××××k×#×f×-"Gthis data is compressed using a Huffman code, specifically one compatible with the Nintendo DS BIOS. it starts with 0x20 bytes encoding the Huffman tree used, then 0x90 bytes of compressed bitstream—the actual compressed file contents
there's a big difference between the two parts that can be hard to notice without the help of colors. the tree mostly has bytes in the range – (plus some low s and s), but the bitstream has bytes evenly distributed throughout the entire range of –
the bitstream is much more colorful and chaotic because good compression algorithms output data that looks visually random. ideally, any patterns you would've noticed in the data were already found by the algorithm, and then used to make the compressed output smaller
...
00000028 00 00 00 00 00 00 00 00 88 00 00 00 00 00 00 00 ⋄⋄⋄⋄⋄⋄⋄⋄×⋄⋄⋄⋄⋄⋄⋄
00000038 00 00 00 00 80 80 80 78 46 77 80 08 00 00 00 00 ⋄⋄⋄⋄×××xFwו⋄⋄⋄⋄
00000048 00 00 00 00 88 44 68 12 21 55 46 74 00 00 00 00 ⋄⋄⋄⋄×Dh•!UFt⋄⋄⋄⋄
00000058 00 00 00 70 25 41 33 53 65 13 54 54 08 00 00 00 ⋄⋄⋄p%A3Se•TT•⋄⋄⋄
00000068 00 00 70 27 22 13 43 B7 9B 67 54 32 76 08 00 00 ⋄⋄p'"•C××gT2v•⋄⋄
00000078 00 00 26 22 76 76 98 BA AA BA 59 21 44 75 00 00 ⋄⋄&"vv××××Y!Du⋄⋄
00000088 00 80 D2 71 99 AA 99 AA A9 AB 99 88 48 43 85 00 ⋄××q××××××××HC×⋄
00000098 00 60 12 A5 A9 9A 99 A9 AA 99 99 CA 48 55 07 00 ⋄`•×××××××××HU•⋄
000000a8 00 38 42 B9 AA 99 9A A9 99 99 89 88 77 78 88 00 ⋄8B×××××××××wx×⋄
000000b8 00 36 86 AA 99 99 B9 AA AA 99 78 78 77 46 75 00 ⋄6××××××××xxwFu⋄
000000c8 80 67 66 A9 99 A9 AA BB BB AA 78 67 57 44 02 08 ×gf×××××××xgWD••
000000d8 80 23 45 98 A9 AB CB BB BB AA 89 77 57 12 95 00 ×#E××××××××wW•×⋄
000000e8 58 2E 55 98 99 BA BB CC BB AB 79 67 56 54 98 00 X.U×××××××ygVT×⋄
000000f8 50 52 87 AA A9 BA BB BB CB BB 89 66 56 55 97 00 PR×××××××××fVU×⋄
00000108 48 43 A5 AA BA BB CC CC CB 9A 88 66 55 34 84 00 HC×××××××××fU4×⋄
00000118 70 44 A8 99 B9 CB CC CC AC 8A 56 45 55 33 05 08 pD××××××××VEU3••
00000128 00 77 CB A9 AA BC CC CC BC 69 45 43 43 22 A5 08 ⋄w×××××××iECC"ו
00000138 80 67 A8 99 BA BB BC CC AB 58 44 33 32 43 A8 00 ×g×××××××XD32C×⋄
00000148 00 34 74 A9 AA BB BB BB 7A 45 23 22 23 41 99 08 ⋄4t×××××zE#"#Aו
00000158 80 46 74 99 99 AA BA AC 7A 34 22 12 23 41 87 80 ×Ft×××××z4"•#A××
00000168 00 17 52 99 89 AA AA BB 58 34 23 21 E2 4E A7 09 ⋄•R×××××X4#!×N×␣
00000178 00 36 73 99 99 98 98 A9 68 35 22 12 12 4E A9 00 ⋄6s×××××h5"••N×⋄
00000188 70 44 88 87 99 88 78 88 66 45 32 21 E1 62 AA 07 pD××××x×fE2!×bו
00000198 70 86 69 65 88 88 68 77 56 44 23 12 21 A7 0A 00 p×ie××hwVD#•!×⏎⋄
000001a8 00 90 57 52 85 77 77 66 66 44 33 D1 42 99 00 00 ⋄×WR×wwffD3×B×⋄⋄
000001b8 00 00 70 56 41 55 65 67 54 35 12 21 63 09 00 00 ⋄⋄pVAUegT5•!c␣⋄⋄
000001c8 00 00 00 8A 44 32 22 22 1E 11 12 43 85 80 00 00 ⋄⋄⋄×D2""•••C××⋄⋄
000001d8 00 00 80 A0 57 55 12 EE 2F 22 32 54 85 08 00 00 ⋄⋄××WU•×/"2Tו⋄⋄
000001e8 00 00 00 80 99 57 33 45 75 57 66 78 A8 00 00 00 ⋄⋄⋄××W3EuWfx×⋄⋄⋄
000001f8 00 00 00 00 08 99 A9 0A 9A A0 A9 9A 08 00 00 00 ⋄⋄⋄⋄•××⏎×××ו⋄⋄⋄
00000208 00 00 00 00 00 90 80 00 80 00 87 80 00 00 00 00 ⋄⋄⋄⋄⋄××⋄×⋄××⋄⋄⋄⋄
00000218 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ⋄⋄⋄⋄⋄⋄⋄⋄⋄⋄⋄⋄⋄⋄⋄⋄
......
00000028 00 00 00 00 00 00 00 00 88 00 00 00 00 00 00 00 ⋄⋄⋄⋄⋄⋄⋄⋄×⋄⋄⋄⋄⋄⋄⋄
00000038 00 00 00 00 80 80 80 78 46 77 80 08 00 00 00 00 ⋄⋄⋄⋄×××xFwו⋄⋄⋄⋄
00000048 00 00 00 00 88 44 68 12 21 55 46 74 00 00 00 00 ⋄⋄⋄⋄×Dh•!UFt⋄⋄⋄⋄
00000058 00 00 00 70 25 41 33 53 65 13 54 54 08 00 00 00 ⋄⋄⋄p%A3Se•TT•⋄⋄⋄
00000068 00 00 70 27 22 13 43 B7 9B 67 54 32 76 08 00 00 ⋄⋄p'"•C××gT2v•⋄⋄
00000078 00 00 26 22 76 76 98 BA AA BA 59 21 44 75 00 00 ⋄⋄&"vv××××Y!Du⋄⋄
00000088 00 80 D2 71 99 AA 99 AA A9 AB 99 88 48 43 85 00 ⋄××q××××××××HC×⋄
00000098 00 60 12 A5 A9 9A 99 A9 AA 99 99 CA 48 55 07 00 ⋄`•×××××××××HU•⋄
000000a8 00 38 42 B9 AA 99 9A A9 99 99 89 88 77 78 88 00 ⋄8B×××××××××wx×⋄
000000b8 00 36 86 AA 99 99 B9 AA AA 99 78 78 77 46 75 00 ⋄6××××××××xxwFu⋄
000000c8 80 67 66 A9 99 A9 AA BB BB AA 78 67 57 44 02 08 ×gf×××××××xgWD••
000000d8 80 23 45 98 A9 AB CB BB BB AA 89 77 57 12 95 00 ×#E××××××××wW•×⋄
000000e8 58 2E 55 98 99 BA BB CC BB AB 79 67 56 54 98 00 X.U×××××××ygVT×⋄
000000f8 50 52 87 AA A9 BA BB BB CB BB 89 66 56 55 97 00 PR×××××××××fVU×⋄
00000108 48 43 A5 AA BA BB CC CC CB 9A 88 66 55 34 84 00 HC×××××××××fU4×⋄
00000118 70 44 A8 99 B9 CB CC CC AC 8A 56 45 55 33 05 08 pD××××××××VEU3••
00000128 00 77 CB A9 AA BC CC CC BC 69 45 43 43 22 A5 08 ⋄w×××××××iECC"ו
00000138 80 67 A8 99 BA BB BC CC AB 58 44 33 32 43 A8 00 ×g×××××××XD32C×⋄
00000148 00 34 74 A9 AA BB BB BB 7A 45 23 22 23 41 99 08 ⋄4t×××××zE#"#Aו
00000158 80 46 74 99 99 AA BA AC 7A 34 22 12 23 41 87 80 ×Ft×××××z4"•#A××
00000168 00 17 52 99 89 AA AA BB 58 34 23 21 E2 4E A7 09 ⋄•R×××××X4#!×N×␣
00000178 00 36 73 99 99 98 98 A9 68 35 22 12 12 4E A9 00 ⋄6s×××××h5"••N×⋄
00000188 70 44 88 87 99 88 78 88 66 45 32 21 E1 62 AA 07 pD××××x×fE2!×bו
00000198 70 86 69 65 88 88 68 77 56 44 23 12 21 A7 0A 00 p×ie××hwVD#•!×⏎⋄
000001a8 00 90 57 52 85 77 77 66 66 44 33 D1 42 99 00 00 ⋄×WR×wwffD3×B×⋄⋄
000001b8 00 00 70 56 41 55 65 67 54 35 12 21 63 09 00 00 ⋄⋄pVAUegT5•!c␣⋄⋄
000001c8 00 00 00 8A 44 32 22 22 1E 11 12 43 85 80 00 00 ⋄⋄⋄×D2""•••C××⋄⋄
000001d8 00 00 80 A0 57 55 12 EE 2F 22 32 54 85 08 00 00 ⋄⋄××WU•×/"2Tו⋄⋄
000001e8 00 00 00 80 99 57 33 45 75 57 66 78 A8 00 00 00 ⋄⋄⋄××W3EuWfx×⋄⋄⋄
000001f8 00 00 00 00 08 99 A9 0A 9A A0 A9 9A 08 00 00 00 ⋄⋄⋄⋄•××⏎×××ו⋄⋄⋄
00000208 00 00 00 00 00 90 80 00 80 00 87 80 00 00 00 00 ⋄⋄⋄⋄⋄××⋄×⋄××⋄⋄⋄⋄
00000218 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ⋄⋄⋄⋄⋄⋄⋄⋄⋄⋄⋄⋄⋄⋄⋄⋄
...this final excerpt is from the bitmap data for the following image:
like all the other examples, it comes from the Nintendo DS game Fossil Fighters. specifically, the hole the player makes when digging for fossils:
because the bitmap uses 4-bit color indices, each digit of the hexdump encodes exactly one pixel of the image. i think the result mostly speaks for itself, but i'd specifically like to point out the highlight at the bottom right of the hole. in the plain hexdump, you might be able to pick out the general shape of the hole—especially if you look at the character panel on the right—but with color, you can pick up an incredible amount of detail!
if you’ve used a hex editor with color-coding before, you may have noticed something different about the way i’m choosing to color-code bytes
most colorful hex editors have a few categories they sort bytes into, like 00 bytes, printable ASCII, ASCII whitespace, other ASCII, non-ASCII, or FF bytes
hexyl, for example, uses the following categories:
⋄ NULL bytes (0x00)
a ASCII printable characters (0x20 - 0x7E)
_ ASCII whitespace (0x09 - 0x0D, 0x20)
• ASCII control characters (except NULL and whitespace)
× Non-ASCII bytes (0x80 - 0xFF) which end up looking something like this:
00 01 10 20 30 40 50 60 70 80 90 A0 B0 C0 D0 E0 F0 FF hexyl colors00000000 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ⋄••••••••__•__••
00000010 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F ••••••••••••••••
00000020 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F !"#$%&'()*+,-./
00000030 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 0123456789:;<=>?
00000040 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F @ABCDEFGHIJKLMNO
00000050 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F PQRSTUVWXYZ[\]^_
00000060 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F `abcdefghijklmno
00000070 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F pqrstuvwxyz{|}~•
00000080 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F ××××××××××××××××
00000090 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F ××××××××××××××××
000000a0 A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF ××××××××××××××××
000000b0 B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF ××××××××××××××××
000000c0 C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF ××××××××××××××××
000000d0 D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF ××××××××××××××××
000000e0 E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF ××××××××××××××××
000000f0 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF ××××××××××××××××these broad categories are enough to pick out common patterns like repeated null bytes and ASCII strings. they also create enough variation to track visually when scrolling, which i find quite helpful. it can be really disorienting to scroll around a fully monochrome hexdump
i, however, am going further, with 18 total groups: one for each leading nybble (0X, 1X, 2X...), plus two extras for 00 andFF:
00 01 10 20 30 40 50 60 70 80 90 A0 B0 C0 D0 E0 F0 FF00000000 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ⋄••••••••→⏎••␍••
00000010 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F ••••••••••••••••
00000020 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F !"#$%&'()*+,-./
00000030 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 0123456789:;<=>?
00000040 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F @ABCDEFGHIJKLMNO
00000050 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F PQRSTUVWXYZ[\]^_
00000060 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F `abcdefghijklmno
00000070 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F pqrstuvwxyz{|}~•
00000080 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F ××××××××××××××××
00000090 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F ××××××××××××××××
000000a0 A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF ××××××××××××××××
000000b0 B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF ××××××××××××××××
000000c0 C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF ××××××××××××××××
000000d0 D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF ××××××××××××××××
000000e0 E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF ××××××××××××××××
000000f0 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF ×××××××××××××××╳having more colors makes it possible to recognize more complex patterns, like the ascending offsets from example 2 or the different sections in example 3. ASCII text is still recognizable, but instead of solid cyan, it's a variated green and orange:
00000000 6C 6F 6F 6B 20 6D 61 2C 20 69 27 6D 20 41 53 43 look ma, i'm ASC
00000010 49 49 21 20 6C 6F 72 65 6D 20 69 70 73 75 6D 20 II! lorem ipsum
00000020 61 6E 64 20 61 6C 6C 20 74 68 61 74 20 69 67 and all that ighexyl's colors00000000 6C 6F 6F 6B 20 6D 61 2C 20 69 27 6D 20 41 53 43 look ma, i'm ASC
00000010 49 49 21 20 6C 6F 72 65 6D 20 69 70 73 75 6D 20 II! lorem ipsum
00000020 61 6E 64 20 61 6C 6C 20 74 68 61 74 20 69 67 and all that ignon-ASCII UTF-8, on the other hand, looks completely different, with its own unique pattern that's only visible if you have a large number of color groups:
00000000 73 6F 6D 65 20 55 54 46 2D 38 3A 20 E3 81 93 E3 some UTF-8: ××××
00000010 82 93 E3 81 AB E3 81 A1 E3 81 AF E3 80 81 E3 82 ××××××××××××××××
00000020 A2 E3 83 AA E3 82 B9 E3 81 A7 E3 81 99 EF BC 81 ××××××××××××××××hexyl's colors00000000 73 6F 6D 65 20 55 54 46 2D 38 3A 20 E3 81 93 E3 some UTF-8: ××××
00000010 82 93 E3 81 AB E3 81 A1 E3 81 AF E3 80 81 E3 82 ××××××××××××××××
00000020 A2 E3 83 AA E3 82 B9 E3 81 A7 E3 81 99 EF BC 81 ××××××××××××××××there are a million more examples i could give, like negative numbers in two's complement )
colorful output in a hexdump is useful for the same reason that syntax highlighting for code is useful: it takes advantage of our brains' powerful visual pattern recognition. it lets us notice details in the data just as quickly as we notice details in the environment around us. color-coded bytes should be as prevalent in hex editors as syntax highlighting is in code editors today
if you currently use xxd, try switching to hexyl! it's pretty nice, and even slightly faster on my machine (with colors off). it doesn't have the full 18 colors that i prefer, but it's certainly way better than plain black and white
unfortunately, i don't have any suggestions for other types of tools :/. if you know any, please let me know! if you work on any tools that show hexdumps, i highly recommend adding colors, ideally with a large number of groups (feel free to copy mine!)
the main goal of this article is to spread awareness that this feature exists. it provides a lot of utility with practically no downside, and more people should be asking for it. if you'd like to submit a feature request for the tool you use most, i hope this article can serve as an explanation for why it's worth adding
while writing this article, i actually started making my own custom hex editor, called hexapoda >_<. it takes inspiration from Helix and Teehee (among others), with modal editing, multiple cursors, and selection-first operations (written in Rust, with Ratatui!). if enough people want, i might polish it up and write some docs so anyone can use it, but for now, it's just for me
xxd or hexyl that show hex but don't let you edit it ⏎entirely human-made,
please don't hesitate to report a mistake or suggest a fix!
discuss on Mastodon or Hacker News