Skip to content

Instantly share code, notes, and snippets.

@jevinskie
Last active August 29, 2023 15:43
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jevinskie/a4ed8a6337e791a07b412a5be9f132af to your computer and use it in GitHub Desktop.
Save jevinskie/a4ed8a6337e791a07b412a5be9f132af to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
import sys
# pip3 install bitstring
from bitstring import BitArray, BitStream
def flip_nibbles(ibb):
obb = bytearray(ibb)
for i in range(len(ibb)):
ib = ibb[i]
in0 = ib & 0xF
in1 = (ib & 0xF0) >> 4
ob = (in0 << 4) | in1
obb[i] = ob
return obb
# works
def comp(in_bytes):
# if len(in_bytes) % 2 == 1:
# in_bytes += b'\xff'
outbs = BitStream()
outflagbs = BitStream()
last_word_idx = 0
for word_idx in range(len(in_bytes)//2):
word = int.from_bytes(in_bytes[word_idx*2:(word_idx+1)*2], byteorder='little')
# print('word: {:04x}'.format(word))
flag_bits = 0
n0 = (word & 0x000F) >> 0
n1 = (word & 0x00F0) >> 4
n2 = (word & 0x0F00) >> 8
n3 = (word & 0xF000) >> 12
comp_word = BitStream()
(n0, n1, n2, n3) = (n0, n1, n2, n3)
if n0 != 0:
# print('n0 {:x}'.format(n0))
flag_bits |= 0b0001
comp_word += BitStream(uint=n0, length=4)
if n1 != 0:
# print('n1 {:x}'.format(n1))
flag_bits |= 0b0010
comp_word += BitStream(uint=n1, length=4)
if n2 != 0:
# print('n2 {:x}'.format(n2))
flag_bits |= 0b0100
comp_word += BitStream(uint=n2, length=4)
if n3 != 0:
# print('n3 {:x}'.format(n3))
flag_bits |= 0b1000
comp_word += BitStream(uint=n3, length=4)
# print('flag_bits: {:04b} {:x}'.format(flag_bits, flag_bits))
# if flag_bits != 0xF:
# flag_bits += 1
outbs += BitStream(uint=flag_bits, length=4)
outbs += comp_word
# outbs += BitStream(uint=flag_bits, length=4)
outflagbs += BitStream(uint=1, length=4)
if len(comp_word) > 0:
outflagbs += BitStream(int=0, length=len(comp_word))
# outflagbs += BitStream(uint=1, length=4)
# if len(comp_word) == 0:
# print('zero comp word')
last_word_idx = word_idx
print('last_word_idx: {} *2: {} len(in_bytes): {}'.format(last_word_idx, last_word_idx*2, len(in_bytes)))
# if len(outbs) % 8 != 0:
# rem = 8 - (len(outbs) % 8)
# outbs += BitStream(uint=0, length=rem)
# outflagbs += BitStream(uint=0, length=rem)
if len(outbs) % 8 != 0:
rem = 8 - (len(outbs) % 8)
outbs += BitStream(int=0, length=rem)
outflagbs += BitStream(uint=0, length=rem)
return (outbs.bytes, outflagbs.bytes)
# broken
def comp2(in_bytes):
ibs = BitStream(bytes=in_bytes)
# ibs = ibs[4:]
outbs = BitStream()
for wordi in range(len(in_bytes)//2):
flag_bits = 0
comp_word = BitStream()
for i in range(4):
# for i in range(3,-1,-1):
biti = wordi*16+4*i
nib = ibs[biti:biti+4]
# print('len {}'.format(len(nib)))
# fb = 1 << (3 - i)
fb = 1 << i
if nib.any('1'):
flag_bits |= fb
comp_word += nib
print('wordi: {} biti: {} nib: {:01x} i: {} fb: {:04b} {:01x} flag_bits: {:04b} {:01x}'.format(wordi, biti, nib.uint, i, fb, fb, flag_bits, flag_bits))
outbs += BitStream(uint=flag_bits, length=4)
outbs += comp_word
if len(outbs) % 8 != 0:
outbs += BitStream(uint=0, length=1) * (8 - (len(outbs) % 8))
return outbs.bytes
inbuf = open(sys.argv[1], 'rb').read()
(outbuf, outflagsbuf) = comp(inbuf)
outbuf += b'\xff\xff' # HACK haven't figured out padding/alignment
outbuf = flip_nibbles(outbuf)
open(sys.argv[2], 'wb').write(outbuf)
open('flag-nibble-locs.bin', 'wb').write(outflagsbuf)
#!/usr/bin/env python3
import sys
# pip3 install bitstring
from bitstring import BitArray, BitStream
def flip_nibbles(ibb):
obb = bytearray(ibb)
for i in range(len(ibb)):
ib = ibb[i]
in0 = ib & 0xF
in1 = (ib & 0xF0) >> 4
ob = (in0 << 4) | in1
obb[i] = ob
return obb
n_flag_bits = 4
n_bits_per_element = 4
def decomp2(in_bytes):
ibs = BitStream(bytes=in_bytes)
outbs = BitStream()
i = 0
while len(ibs) > 0:
flag_bits = ibs[:n_flag_bits]
del ibs[:n_flag_bits]
flag_bits.reverse()
for j, b in enumerate(flag_bits):
if b:
outbs += ibs[:n_bits_per_element]
del ibs[:n_bits_per_element]
else:
outbs += BitStream(uint=0, length=n_bits_per_element)
i += 1
if len(outbs) % 8 != 0:
outbs += BitStream(uint=0, length=(8 - (len(outbs) % 8)))
return flip_nibbles(outbs.bytes)
inbuf = open(sys.argv[1], 'rb').read()
inbuf = flip_nibbles(inbuf)
outbuf = decomp2(inbuf)
open(sys.argv[2], 'wb').write(outbuf)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment