binary
Work with bytes: make them from hex or lists, pack and unpack numbers the way file formats and network protocols store them (like Python's struct), read little- and big-endian numbers at an offset, show a hex dump, measure entropy, and sniff what kind of file something is. Write bytes as b"..." in TB.
import binary
Example
import binary
# A tiny file header: magic, version (16-bit), record count (32-bit), little-endian
let header = binary.pack("<4sHI", b"TBDB", 3, 1200)
say(header.hex())
let [magic, version, count] = binary.unpack("<4sHI", header)
say(magic, version, count)
say(binary.read_u16be(b"\x01\xbb")) # 443, as a network protocol stores it
say(binary.hexdump(b"MZ\x90\x00 tiny header"))
say(binary.entropy(b"aaaaaaaa"), binary.entropy(binary.from_list(range(256))))
say(binary.sniff(b"%PDF-1.7\n").type)
Functions
from_hex(text)
returns bytesBytes from hex text: from_hex("4d5a90") is b"MZ\x90". Spaces and colons are ignored.
Visualizehow binary.from_hex works
binary.from_hex("4d5a9000") gives b"MZ\x90\x00"binary.from_hex("4d:5a:90:00") gives b"MZ\x90\x00"binary.from_hex("7f454c46") gives b"\x7fELF"
Real result: worked out by running this example with TB while the site was built.
to_hex(data, separator?)
returns textThe bytes as hex text: to_hex(b"MZ") is "4d5a"; to_hex(b"MZ", " ") is "4d 5a".
Visualizehow binary.to_hex works
binary.to_hex(b"MZ\x90\x00", "") gives "4d5a9000"binary.to_hex(b"MZ\x90\x00", " ") gives "4d 5a 90 00"binary.to_hex(b"MZ\x90\x00", ":") gives "4d:5a:90:00"
Drawing…
Real result: worked out by running this example with TB while the site was built.
from_list(numbers)
returns bytesBytes from a list of numbers 0 to 255: from_list([77, 90]) is b"MZ".
Visualizehow binary.from_list works
binary.from_list([77, 90, 144, 0]) gives b"MZ\x90\x00"
Real result: worked out by running this example with TB while the site was built.
from_text(text, encoding?)
returns bytesThe text as bytes (UTF-8 unless you name another encoding). Same as text.bytes().
Visualizehow binary.from_text works
binary.from_text("héllo", "utf-8") gives b"h\xc3\xa9llo"binary.from_text("héllo", "latin-1") gives b"h\xe9llo"binary.from_text("héllo", "utf-16-le") gives b"h\x00\xe9\x00l\x00l\x00o\x00"
Drawing…
Real result: worked out by running this example with TB while the site was built.
zeros(n)
returns bytesn zero bytes.
Visualizehow binary.zeros works
binary.zeros(2) gives b"\x00\x00"binary.zeros(4) gives b"\x00\x00\x00\x00"binary.zeros(8) gives b"\x00\x00\x00\x00\x00\x00\x00\x00"
Real result: worked out by running this example with TB while the site was built.
concat(data, ...)
returns bytesJoin bytes (or a list of bytes) into one.
Visualizehow binary.concat works
binary.concat(b"MZ", b"\x90\x00", b"PE") gives b"MZ\x90\x00PE"
Real result: worked out by running this example with TB while the site was built.
size(format)
returns numberHow many bytes pack(format, ...) makes: size("<HI") is 6.
Visualizehow binary.size works
binary.size("<HI") gives 6binary.size("<B") gives 1binary.size("<Q") gives 8binary.size(">HHI") gives 8
Real result: worked out by running this example with TB while the site was built.
pack(format, value, ...)
returns bytesNumbers (and bytes) packed the way file formats store them. pack("<HI", 1, 2) is 6 bytes, little-endian.
Format letters
<little-endian (the default).- > or !: big-endian.
- B b H h I i Q q: whole numbers. A capital letter means unsigned.
- B b: 8-bit
- H h: 16-bit
- I i: 32-bit
- Q q: 64-bit
- f d: 32-bit and 64-bit decimals.
NsN bytes, like 4s.xa zero byte.
Visualizehow binary.pack works
binary.pack("<HI", 1, 2) gives b"\x01\x00\x02\x00\x00\x00"binary.pack(">HI", 1, 2) gives b"\x00\x01\x00\x00\x00\x02"
Real result: worked out by running this example with TB while the site was built.
unpack(format, data, offset?)
returns listRead numbers out of bytes, starting at offset (default 0): unpack("<HI", data) gives [first, second]. Same format letters as pack().
Visualizehow binary.unpack works
binary.unpack("<HI", b"\x01\x00\x02\x00\x00\x00", 0) gives [1, 2]binary.unpack(">HI", b"\x01\x00\x02\x00\x00\x00", 0) gives [256, 33554432]
Real result: worked out by running this example with TB while the site was built.
read_u8(data, offset?)
returns numberThe unsigned 8-bit little-endian number at offset (default 0).
Visualizehow binary.read_u8 works
binary.read_u8(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 0) gives 77binary.read_u8(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 2) gives 144binary.read_u8(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 4) gives 3binary.read_u8(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 8) gives 255
Drawing…
Real result: worked out by running this example with TB while the site was built.
read_i8(data, offset?)
returns numberThe signed 8-bit little-endian number at offset (default 0).
Visualizehow binary.read_i8 works
binary.read_i8(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 0) gives 77binary.read_i8(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 2) gives -112binary.read_i8(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 4) gives 3binary.read_i8(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 8) gives -1
Drawing…
Real result: worked out by running this example with TB while the site was built.
read_u16le(data, offset?)
returns numberThe unsigned 16-bit little-endian number at offset (default 0).
Visualizehow binary.read_u16le works
binary.read_u16le(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 0) gives 23117binary.read_u16le(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 2) gives 144binary.read_u16le(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 4) gives 3binary.read_u16le(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 8) gives 65535
Drawing…
Real result: worked out by running this example with TB while the site was built.
read_i16le(data, offset?)
returns numberThe signed 16-bit little-endian number at offset (default 0).
Visualizehow binary.read_i16le works
binary.read_i16le(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 0) gives 23117binary.read_i16le(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 2) gives 144binary.read_i16le(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 4) gives 3binary.read_i16le(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 8) gives -1
Drawing…
Real result: worked out by running this example with TB while the site was built.
read_u16be(data, offset?)
returns numberThe unsigned 16-bit big-endian number at offset (default 0).
Visualizehow binary.read_u16be works
binary.read_u16be(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 0) gives 19802binary.read_u16be(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 2) gives 36864binary.read_u16be(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 4) gives 768binary.read_u16be(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 8) gives 65535
Drawing…
Real result: worked out by running this example with TB while the site was built.
read_i16be(data, offset?)
returns numberThe signed 16-bit big-endian number at offset (default 0).
Visualizehow binary.read_i16be works
binary.read_i16be(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 0) gives 19802binary.read_i16be(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 2) gives -28672binary.read_i16be(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 4) gives 768binary.read_i16be(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 8) gives -1
Drawing…
Real result: worked out by running this example with TB while the site was built.
read_u32le(data, offset?)
returns numberThe unsigned 32-bit little-endian number at offset (default 0).
Visualizehow binary.read_u32le works
binary.read_u32le(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 0) gives 9460301binary.read_u32le(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 2) gives 196752binary.read_u32le(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 4) gives 3binary.read_u32le(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 8) gives 4278190079
Drawing…
Real result: worked out by running this example with TB while the site was built.
read_i32le(data, offset?)
returns numberThe signed 32-bit little-endian number at offset (default 0).
Visualizehow binary.read_i32le works
binary.read_i32le(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 0) gives 9460301binary.read_i32le(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 2) gives 196752binary.read_i32le(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 4) gives 3binary.read_i32le(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 8) gives -16777217
Drawing…
Real result: worked out by running this example with TB while the site was built.
read_u32be(data, offset?)
returns numberThe unsigned 32-bit big-endian number at offset (default 0).
Visualizehow binary.read_u32be works
binary.read_u32be(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 0) gives 1297780736binary.read_u32be(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 2) gives 2415919872binary.read_u32be(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 4) gives 50331648binary.read_u32be(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 8) gives 4294967294
Drawing…
Real result: worked out by running this example with TB while the site was built.
read_i32be(data, offset?)
returns numberThe signed 32-bit big-endian number at offset (default 0).
Visualizehow binary.read_i32be works
binary.read_i32be(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 0) gives 1297780736binary.read_i32be(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 2) gives -1879047424binary.read_i32be(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 4) gives 50331648binary.read_i32be(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 8) gives -2
Drawing…
Real result: worked out by running this example with TB while the site was built.
read_u64le(data, offset?)
returns numberThe unsigned 64-bit little-endian number at offset (default 0).
Visualizehow binary.read_u64le works
binary.read_u64le(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 0) gives 12894362189binary.read_u64le(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 4) gives 18374686475376656387binary.read_u64le(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 8) gives 289077008678256639
Drawing…
Real result: worked out by running this example with TB while the site was built.
read_i64le(data, offset?)
returns numberThe signed 64-bit little-endian number at offset (default 0).
Visualizehow binary.read_i64le works
binary.read_i64le(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 0) gives 12894362189binary.read_i64le(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 4) gives -72057598332895229binary.read_i64le(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 8) gives 289077008678256639
Drawing…
Real result: worked out by running this example with TB while the site was built.
read_u64be(data, offset?)
returns numberThe unsigned 64-bit big-endian number at offset (default 0).
Visualizehow binary.read_u64be works
binary.read_u64be(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 0) gives 5573925818549141504binary.read_u64be(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 4) gives 216172786408751102binary.read_u64be(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 8) gives 18446744065136526084
Drawing…
Real result: worked out by running this example with TB while the site was built.
read_i64be(data, offset?)
returns numberThe signed 64-bit big-endian number at offset (default 0).
Visualizehow binary.read_i64be works
binary.read_i64be(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 0) gives 5573925818549141504binary.read_i64be(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 4) gives 216172786408751102binary.read_i64be(b"MZ\x90\x00\x03\x00\x00\x00\xff\xff\xff\xfe\x01\x02\x03\x04", 8) gives -8573025532
Drawing…
Real result: worked out by running this example with TB while the site was built.
hexdump(data, width?)
returns textA classic hex dump: offset, hex bytes and the printable characters, width bytes per row (default 16).
Visualizehow binary.hexdump works
binary.hexdump(b"MZ\x90\x00This program cannot", 4) gives "00000000 4d 5a 90 00 |MZ..|\n00000004 54 68 69 73 |This|\n00000008 20 70 72 6f | p…binary.hexdump(b"MZ\x90\x00This program cannot", 8) gives "00000000 4d 5a 90 00 54 68 69 73 |MZ..This|\n00000008 20 70 72 6f 67 72 61 6d | prog…binary.hexdump(b"MZ\x90\x00This program cannot", 16) gives "00000000 4d 5a 90 00 54 68 69 73 20 70 72 6f 67 72 61 6d |MZ..This program|\n00000010 …
Drawing…
Real result: worked out by running this example with TB while the site was built.
entropy(data)
returns numberShannon entropy from 0 (all the same byte) to 8 (random). Packed or encrypted data is usually above 7.2.
Visualizehow binary.entropy works
binary.entropy(b"AAAAAAAA") gives 0binary.entropy("hello world") gives 2.8454binary.entropy(binary.from_hex("8f3a91c2e07d5b16")) gives 3
Real result: worked out by running this example with TB while the site was built.
xor(data, key)
returns bytesEach byte XORed with the key (bytes, repeated; or one number 0-255). XOR twice to get the original back.
Visualizehow binary.xor works
binary.xor(b"hi", 42) gives b"BC"binary.xor(b"hi", 0) gives b"hi"binary.xor(b"hi", 255) gives b"\x97\x96"binary.xor(b"hi", b"k") gives b"\x03\x02"
Drawing…
Real result: worked out by running this example with TB while the site was built.
file_type(path)
returns mapWhat kind of file this is, from its first bytes (not its name): {type, description, mime, extension, path, size}. Knows PE, ELF, Mach-O, PDF, ZIP, PNG, JPEG, GIF, gzip and more.
Visualizehow binary.file_type works
binary.file_type("apps/data/sample.pcap") gives {"type": "pcap", "description": "Network capture (pcap)", "mime": "application/vnd.tcpdum…binary.file_type("apps/data/sample.evtx") gives {"type": "evtx", "description": "Windows event log (EVTX)", "mime": "application/x-ms-evt…binary.file_type("notes.txt") gives {"type": "text", "description": "Plain text", "mime": "text/plain", "extension": ".txt", …
Real result: worked out by running this example with TB while the site was built.
sniff(data)
returns mapLike file_type(), but for bytes you already have: {type, description, mime, extension}.
Visualizehow binary.sniff works
binary.sniff(binary.from_hex("504b0304")) gives {"type": "zip", "description": "ZIP archive", "mime": "application/zip", "extension": ".z…binary.sniff(binary.from_hex("25504446")) gives {"type": "pdf", "description": "PDF document", "mime": "application/pdf", "extension": ".…binary.sniff(b"MZ\x90\x00") gives {"type": "text", "description": "Plain text", "mime": "text/plain", "extension": ".txt", …
Real result: worked out by running this example with TB while the site was built.