Last active
May 22, 2018 21:09
-
-
Save James-E-A/8bc00be773d20b81e642b640ca28a887 to your computer and use it in GitHub Desktop.
Hamming ([24,48] so far)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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