Skip to content

Instantly share code, notes, and snippets.

@JamesTheAwesomeDude
Last active May 22, 2018 21:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JamesTheAwesomeDude/8bc00be773d20b81e642b640ca28a887 to your computer and use it in GitHub Desktop.
Save JamesTheAwesomeDude/8bc00be773d20b81e642b640ca28a887 to your computer and use it in GitHub Desktop.
Hamming ([24,48] so far)
#!/usr/bin/env python
# Copyright 2018 James Edington
# Permission is given to use, modify,
# and redistribute (including modifications)
# in accordance with the MIT license available at
# https://opensource.org/licenses/MIT
# Version 0.0.3, May 22 2018
def __main__():
from sys import argv,getfilesystemencoding
from codecs import register_error
if len(argv) == 1:
# Being run with no arguments
__demo__()
elif len(argv) == 3:
raise NotImplementedError("STDIO/CMD interface TODO!\nFor now, just use the API.")
# Three arguments, assuming first is message
code=(int([2]),int(argv[3]))
#enc=getfilesystemencoding()
enc='utf-8'
register_error(enc, lambda e:(e.object[e.start:e.end].encode(enc),e.end))
# https://stackoverflow.com/q/50475239/1874170#comment87965447_50475239
data=argv[1].encode('iso-8859-1', errors=enc)
def __demo__():
code=(24,18)
# 0/4 | 192/255 | 168/255
data = 0b001100000010101000.to_bytes(3, byteorder='big')
print('Data in:\t{}'.format(' ' * (code[1]%8) + ' '.join([format(i, "08b") for i in data])[code[1]%8:]))
encoded = hamming(data, code)
print('Encoded:\t{}'.format(' ' * (code[0]%8) + ' '.join([format(i, "08b") for i in encoded])[code[0]%8:]))
def _xor(items):
i=0x00
for item in items:
i ^= item
return i
_mask_le = lambda B, i: B & 0b0000001 << i
# _index_le(0b0001, 0) == 1 and _index_le(0b1011, 2) == 0
# Negative indices TODO, perhaps infeasible due to non-existant "left" boundary
_index_le = lambda B, i: _mask_le(B,i) >> i
def hamming(data, code):
assert code in check_mask and code in encode_table
# Ensure the data is of appropriate length
assert -(-code[1] // 8) == len(data) # https://stackoverflow.com/a/33300093/1874170
# https://pdc.ro.nu/hamming.html
check_mask={
(24,18):[
(1,[17,15,13,11,10, 8, 6, 4, 3, 1, 0]),
(1,[17,16,13,12,10, 9, 6, 5, 3, 2, 0]),
(1,[17,16,15,14,10, 9, 8, 7, 3, 2, 1]),
(1,[10, 9, 8, 7, 6, 5, 4]),
(1,[17,16,15,14,13,12,11]),
(0,[17,14,12,11,10, 7, 5, 4, 2, 1, 0])
]
}
encode_table={
(24,18):[
[( 1, 3),( 0, 3),( 0, 2),( 0, 1),( 1, 2),( 0, 0),( 1, 1),( 1, 0)],
[( 1, 4),( 0,10),( 0, 9),( 0, 8),( 0, 7),( 0, 6),( 0, 5),( 0, 4)],
[( 1, 5),( 0,17),( 0,16),( 0,15),( 0,14),( 0,13),( 0,12),( 0,11)]
]
}
chex_int=0x00
data_int=int.from_bytes(data, byteorder='big')
I=0
for B in check_mask[code]:
chex_int ^= (
_xor(
[B[0]] +
[_index_le(data_int, i) for i in B[1]]
) << I
)
I += 1
encoded=bytearray()
bc_int=(data_int,chex_int)
I=0
for B in encode_table[code]:
x=0x00
i=0
for b in B:
x ^= _index_le(bc_int[b[0]], b[1]) << i
i += 1
encoded.append(x)
I += 1
return bytes(encoded)
__name__ == "__main__" and __main__()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment