data::conversion

encoding bash · python hex · base64
Bits & Bytes Reference Table ASCII Hex Binary Base64/32 Slice & Pack Netcat / Raw File Ops Pipelines
01Bits, Bytes & Units
Anatomy of a byte
bit 71
bit 61
bit 50
bit 41
bit 30
bit 20
bit 11
bit 00
# 11010010 = 0xD2 = 210 decimal = 'Ò' ASCII
# bit 7 = MSB (most significant bit)
# bit 0 = LSB (least significant bit)
# 1 byte = 8 bits
# 1 nibble = 4 bits = 1 hex digit (0-F)
Size reference
UnitBitsBytesValues
bit10 or 1
nibble4½0–15 (0x0–0xF)
byte810–255 (0x00–0xFF)
word1620–65535
dword3240–4,294,967,295
qword6480–2⁶⁴−1
uint8810–255
int881−128–127
uint323240–4,294,967,295
uint646480–18,446,744,073,709,551,615
Endianness
# Value: 0xDEADBEEF
# Big-endian    (network order): DE AD BE EF
# Little-endian (x86/x64):       EF BE AD DE

# Python pack/unpack
import struct
struct.pack('>I', 0xDEADBEEF)   # → b'\xde\xad\xbe\xef'  big
struct.pack('<I', 0xDEADBEEF)   # → b'\xef\xbe\xad\xde'  little
struct.unpack('<I', b'\xef\xbe\xad\xde')[0]  # → 3735928559

# struct format characters:
# > = big-endian    < = little-endian    ! = network (big)
# B = uint8   H = uint16   I = uint32   Q = uint64
# b = int8    h = int16    i = int32    q = int64
Bit operations (Python)
# Bitwise operators
0b1010 &  0b1100   # → 0b1000  AND
0b1010 |  0b1100   # → 0b1110  OR
0b1010 ^  0b1100   # → 0b0110  XOR
~0b1010            # → -11     NOT (two's complement)
0b0001 << 3        # → 0b1000  left shift = multiply by 2
0b1000 >> 2        # → 0b0010  right shift = divide by 2

# Extract specific bits
val = 0b11010110
bit3 = (val >> 3) & 1     # → bit 3 = 0
nibble_hi = (val >> 4)    # → upper nibble = 0b1101 = 13
nibble_lo = val & 0x0F    # → lower nibble = 0b0110 = 6

# Set/clear/toggle a bit
val |=  (1 << 3)   # set   bit 3
val &= ~(1 << 3)   # clear bit 3
val ^=  (1 << 3)   # toggle bit 3
02Conversion Reference Table
Dec / Hex / Bin / ASCII (0–127)
DecHexBinASCII DecHexBinASCII DecHexBinASCII DecHexBinASCII
320x2000100000SPACE480x30001100000650x4101000001A970x6101100001a
330x2100100001!490x31001100011660x4201000010B980x6201100010b
360x2400100100$570x39001110019900x5A01011010Z1220x7A01111010z
100x0A00001010LF \n130x0D00001101CR \r90x0900001001TAB \t00x0000000000NULL
1230x7B01111011{1250x7D01111101}950x5F01011111_1270x7F01111111DEL
# Printable ASCII range: 32 (space) → 126 (~)
# Uppercase A-Z:  0x41–0x5A (65–90)   lowercase a-z: 0x61–0x7A (97–122)
# Digits 0-9:     0x30–0x39 (48–57)   lowercase = uppercase | 0x20
# picoCTF{ = 70 69 63 6F 43 54 46 7B    (hex)
03ASCII Conversions
bashASCII ↔ char
# Decimal → char
printf '\x70'            # → p  (hex escape)
printf '%b' '\x70'       # → p
printf '\160'            # → p  (octal: 160 octal = 0x70 = 112 dec)
echo -e "\x70\x69\x63"   # → pic

# Char → decimal/hex
printf '%d' "'p"         # → 112  (decimal of 'p')
printf '%x' "'p"         # → 70   (hex of 'p')

# String → hex dump
echo -n "picoCTF" | xxd
echo -n "picoCTF" | xxd -p   # → 7069636f435446 (no spaces)
echo -n "picoCTF" | od -An -tx1

# od formats: -tx1 hex bytes, -td1 decimal, -tb octal
pythonASCII ↔ char
# char → int
ord('p')                  # → 112
ord('p') == 0x70          # → True

# int → char
chr(112)                   # → 'p'
chr(0x70)                  # → 'p'

# string → bytes → list of ints
list(b'picoCTF')           # → [112, 105, 99, 111, 67, 84, 70]
b'picoCTF'.hex()           # → '7069636f435446'

# list of ints → string
''.join(chr(c) for c in [112,105,99])  # → 'pic'
bytes([112,105,99]).decode()           # → 'pic'

# bytes ↔ string
"hello".encode()           # → b'hello'
b'hello'.decode()          # → 'hello'
b'hello'.decode('latin-1') # for non-UTF8 bytes
04Hexadecimal
bashHex conversions
# Dec → hex
printf '%x\n' 255         # → ff
printf '%X\n' 255         # → FF (uppercase)
printf '%08x\n' 255       # → 000000ff (zero-padded 8 chars)
echo "obase=16; 255" | bc   # → FF

# Hex → dec
printf '%d\n' 0xff         # → 255
echo "ibase=16; FF" | bc    # → 255  (uppercase required for bc)
$(( 16#ff ))                # → 255  (bash arithmetic)

# Hex string → bytes → file
echo "7069636f435446" | xxd -r -p       # → picoCTF
echo "7069636f435446" | xxd -r -p > out.bin

# Hex dump a file
xxd file.bin
xxd -p file.bin             # plain hex, no offsets
xxd -l 16 file.bin          # first 16 bytes only
xxd -s 0x100 file.bin       # start at offset 0x100
pythonHex conversions
# Int → hex string
hex(255)                    # → '0xff'
f'{255:#010x}'              # → '0x000000ff' (padded)
f'{255:08x}'                # → '000000ff'  (no prefix)
f'{255:02X}'                # → 'FF'

# Hex string → int
int('ff', 16)               # → 255
int('0xff', 16)             # → 255
int('0xdeadbeef', 0)        # → auto-detect base

# Hex string → bytes
bytes.fromhex('7069636f')   # → b'pico'
import binascii
binascii.unhexlify('7069636f')  # → b'pico'

# Bytes → hex string
b'pico'.hex()               # → '7069636f'
b'pico'.hex(':')            # → '70:69:63:6f' (separator)
binascii.hexlify(b'pico')   # → b'7069636f'
05Binary
bashBinary conversions
# Dec → binary
echo "obase=2; 65" | bc      # → 1000001
printf '%08d\n' $(echo "obase=2; 65" | bc)  # → 01000001

# Binary → dec
echo "ibase=2; 01000001" | bc # → 65
$(( 2#01000001 ))              # → 65  (bash arithmetic)

# Binary string → bytes → ASCII (your image challenge!)
python3 -c "
bits = open('data.txt').read().replace('\n','').replace(' ','')
data = bytes(int(bits[i:i+8],2) for i in range(0,len(bits),8))
open('out.bin','wb').write(data)
"
file out.bin                   # check type

# Count bits set (popcount)
python3 -c "print(bin(0xFF).count('1'))"  # → 8
pythonBinary conversions
# Int → binary string
bin(65)                     # → '0b1000001'
f'{65:08b}'                 # → '01000001' (8-bit, zero-padded)
f'{65:b}'                   # → '1000001'  (no padding)

# Binary string → int
int('01000001', 2)          # → 65
int('0b01000001', 2)        # → 65

# Bytes → binary string (per byte)
for b in b'Hi':
    print(f'{b:08b}')        # → 01001000  01101001

# Binary string → bytes
bits = '0100100001101001'    # 'Hi'
data = bytes(int(bits[i:i+8],2) for i in range(0,len(bits),8))
# → b'Hi'

# All formats at once
n = 65
print(bin(n), oct(n), hex(n), n)  # 0b1000001 0o101 0x41 65
06Base64, Base32, Base16
bashEncode & decode
# Base64 encode / decode
echo -n "picoCTF" | base64       # → cGljb0NURg==
echo "cGljb0NURg==" | base64 -d  # → picoCTF

# File encode / decode
base64 file.bin > file.b64
base64 -d file.b64 > file.bin

# Base32
echo -n "picoCTF" | base32       # → OBWGKYLTEB3W4===
echo "OBWGKYLTEB3W4===" | base32 -d

# Remove newlines from base64 output
base64 file.bin | tr -d '\n'

# URL-safe base64 (- and _ instead of + and /)
echo -n "hello" | base64 | tr '+/' '-_' | tr -d '='
pythonBase64/32/16
import base64

# Base64
base64.b64encode(b'picoCTF')       # → b'cGljb0NURg=='
base64.b64decode('cGljb0NURg==')  # → b'picoCTF'

# URL-safe base64
base64.urlsafe_b64encode(b'data')
base64.urlsafe_b64decode('ZGF0YQ==')

# Base32
base64.b32encode(b'picoCTF')       # → b'OBWGKYLTEB3W4==='
base64.b32decode('OBWGKYLTEB3W4===')

# Base16 (= hex uppercase)
base64.b16encode(b'pico')          # → b'7069636F'
base64.b16decode('7069636F')       # → b'pico'

# Handle missing padding
s = 'cGljb0NURg'   # missing ==
base64.b64decode(s + '==' * (4 - len(s)%4 if len(s)%4 else 0))
07Slice, Pack & Cut Data
bashCut & slice
# cut — extract fields/columns
echo "aa:bb:cc:dd" | cut -d: -f2     # → bb
echo "aa:bb:cc:dd" | cut -d: -f2-4   # → bb:cc:dd
echo "abcdef"     | cut -c3-5        # → cde (chars 3-5)

# dd — extract raw bytes from file
dd if=file.bin of=out.bin bs=1 skip=16 count=4   # bytes 16-19
dd if=file.bin of=out.bin bs=512 skip=2 count=1  # block 2

# head / tail — byte ranges
head -c 16 file.bin          # first 16 bytes
tail -c 16 file.bin          # last 16 bytes
tail -c +17 file.bin         # from byte 17 to end

# Combine: extract bytes 10-20
head -c 20 file.bin | tail -c +11
pythonSlice & pack
# Bytes slicing
data = b'\x00\x01\x02\x03\x04\x05\x06\x07'
data[2:5]                   # → b'\x02\x03\x04'
data[:4]                    # → first 4 bytes
data[4:]                    # → from byte 4 to end
data[::2]                   # → every other byte
data[::-1]                  # → reversed

# struct — parse binary data
import struct
# Unpack: big-endian uint32 at offset 0
struct.unpack_from('>I', data, offset=0)  # → (66051,)
# Pack multiple values
struct.pack('>HHI', 1, 2, 0xdeadbeef)   # → 8 bytes

# Split into N-byte chunks
n = 4
chunks = [data[i:i+n] for i in range(0, len(data), n)]

# int.to_bytes / from_bytes
(0xdeadbeef).to_bytes(4, 'big')     # → b'\xde\xad\xbe\xef'
int.from_bytes(b'\xde\xad\xbe\xef', 'big')  # → 3735928559
08Sending Raw Data — Netcat & Sockets
bashNetcat / raw bytes
# Send plain string
echo "hello" | nc host 1337

# Send WITHOUT trailing newline
echo -n "hello" | nc host 1337
printf "hello" | nc host 1337

# Send raw hex bytes
printf '\xde\xad\xbe\xef' | nc host 1337
echo "deadbeef" | xxd -r -p | nc host 1337

# Send binary file
cat payload.bin | nc host 1337
nc host 1337 < payload.bin

# Interactive: keep connection open after sending
(echo "input"; cat) | nc host 1337

# Send multiple lines with delay
{ echo "line1"; sleep 1; echo "line2"; } | nc host 1337

# Build payload inline and send
python3 -c "import sys; sys.stdout.buffer.write(b'A'*40 + b'\xef\xbe\xad\xde')" \
  | nc host 1337
pythonsocket / pwntools
# Raw socket
import socket
s = socket.socket()
s.connect(('host', 1337))

s.send(b'hello\n')               # send bytes
s.send(bytes.fromhex('deadbeef'))
print(s.recv(1024))               # receive up to 1024 bytes
s.close()

# pwntools (best for CTF)
from pwn import *
p = remote('host', 1337)
# or local: p = process('./challenge')

p.recvuntil(b'Enter: ')          # wait for prompt
p.sendline(b'answer')            # send + \n
p.send(b'\xde\xad\xbe\xef')      # raw bytes, no \n
p.sendlineafter(b'> ', b'cmd')   # wait then send
data = p.recvline()               # read one line
p.interactive()                   # manual shell
Build payloads for nc
# Pattern: read prompt → compute answer → send
python3 -c "
import socket, struct

s = socket.socket()
s.connect(('host', 1337))

# Read challenge
data = s.recv(1024)
print('Got:', data)

# Build response (example: send 4-byte little-endian int)
answer = struct.pack('

# One-liner for simple sends
python3 -c "print('A'*100)" | nc host 1337
python3 -c "import sys; sys.stdout.buffer.write(b'\x00'*8)" | nc host 1337

# ncat with ssl
ncat --ssl host 1337
09File Byte Operations
bashRead & write raw bytes
# Write hex bytes to file
echo "deadbeef0102030405" | xxd -r -p > out.bin
printf '\xde\xad\xbe\xef' > out.bin

# Append bytes
printf '\x00\x01' >> out.bin

# Check file size in bytes
wc -c < file.bin
stat -c %s file.bin
ls -la file.bin

# Search for byte pattern in file
grep -boa $'\xde\xad' file.bin    # byte offset of pattern
xxd file.bin | grep "dead"

# Patch a byte at offset (example: offset 10, byte 0x41)
printf '\x41' | dd of=file.bin bs=1 seek=10 conv=notrunc

# Split file at byte boundary
split -b 512 file.bin chunk_   # 512-byte chunks
pythonRead & write raw bytes
# Read entire file as bytes
data = open('file.bin', 'rb').read()

# Write bytes
open('out.bin', 'wb').write(b'\xde\xad\xbe\xef')

# Patch byte at offset
data = bytearray(open('file.bin','rb').read())
data[10] = 0x41               # patch offset 10
data[10:14] = b'\xde\xad\xbe\xef'  # patch 4 bytes
open('patched.bin','wb').write(data)

# Search for pattern
pos = data.find(b'\xde\xad')   # → byte offset or -1
all_pos = [i for i in range(len(data)) if data[i:i+2] == b'\xde\xad']

# Hexdump (manual)
for i in range(0, min(64, len(data)), 16):
    chunk = data[i:i+16]
    print(f'{i:04x}', chunk.hex(' '), '|', chunk.decode('latin-1'))
10Conversion Pipelines
bashCommon one-liners
# Hex string → ASCII text
echo "7069636f4354467b74657374 7d" | tr -d ' ' | xxd -r -p   # → picoCTF{test}

# Binary string → ASCII (like the image challenge)
python3 -c "
bits='0111000001101001011000110110111101000011010101000100011001111011'
print(bytes(int(bits[i:i+8],2) for i in range(0,len(bits),8)).decode())
"                                                                # → picoCTF{

# Decimal list → ASCII
python3 -c "print(bytes([112,105,99,111,67,84,70]).decode())"  # → picoCTF

# Base64 → hex
echo "cGljb0NURg==" | base64 -d | xxd -p                     # → 7069636f435446

# Hex → base64
echo "7069636f435446" | xxd -r -p | base64                  # → cGljb0NURg==

# ROT13
echo "cvpbPGS{...}" | tr 'A-Za-z' 'N-ZA-Mn-za-m'

# URL encode
python3 -c "from urllib.parse import quote; print(quote('hello world'))"
# URL decode
python3 -c "from urllib.parse import unquote; print(unquote('hello%20world'))"

# String → little-endian 64-bit int (for stack overflow payloads)
python3 -c "import struct; print(struct.pack('<Q', 0x401234).hex())"  # → 341240000000000
pythonSwiss-army conversion function
# Drop this at the top of any CTF solve script
from pwn import *        # p8/p16/p32/p64, u8/u16/u32/u64, xor, enhex, unhex
import base64, struct, binascii

# pwntools shortcuts
p32(0xdeadbeef)            # → b'\xef\xbe\xad\xde'  (little-endian)
p64(0xdeadbeef)            # → 8 bytes LE
u32(b'\xef\xbe\xad\xde')  # → 0xdeadbeef
xor(b'data', b'key')      # → XOR bytes
enhex(b'pico')            # → '7069636f'
unhex('7069636f')         # → b'pico'

# Common conversions table
string → bytes  : s.encode()   or  b'literal'
bytes  → string : b.decode()   or  b.decode('latin-1')
bytes  → hex    : b.hex()      or  enhex(b)
hex    → bytes  : bytes.fromhex(h)  or  unhex(h)
int    → bytes  : n.to_bytes(length, 'little')
bytes  → int    : int.from_bytes(b, 'little')
int    → b64    : base64.b64encode(n.to_bytes(...))
bits   → bytes  : bytes(int(bits[i:i+8],2) for i in range(0,len(bits),8))
QUICK REFERENCE →  1 byte = 8 bits = 2 hex digits = 1 ASCII char (if printable)  · hex↔bytes: xxd -r -p / bytes.fromhex()  · raw to nc: printf '\xde\xad' | nc host port  · binary→bytes: int(bits[i:i+8], 2) per 8-bit chunk  · endian pack: struct.pack('<I', val) little / '>I' big  · pwntools: p32/p64/u32/u64 for exploit payloads