def rs_encode(in_bits, n, k, **kwargs): byte_len = 8 coder = rs.RSCoder(n, k) # Add 0s to end of in_bits to make multiple of k bytes (if necessary) in_bits = pad_to_multiple(in_bits, byte_len * k) # Convert to Decimal dec_array = np.array(co.bin2dec(in_bits, byte_len)) # reshape for coder input dec_array = dec_array.reshape(-1, k) cc_str = ''.join(coder.encode_fast(x) for x in dec_array) # Convert to decimal cc_dec = co.char2dec(cc_str) # convert to binary cc_bits = co.dec2bin(cc_dec, byte_len) # Interleave if ('bInterleave' in kwargs): bIntlv = kwargs['bInterleave'] else: bIntlv = False intlv = np.arange(len(cc_bits)) if bIntlv: np.random.shuffle(intlv) cc_bits = cc_bits[intlv] # return cc_bits, dec_array, cc_str, in_bits, intlv return cc_bits, intlv
def encode(input, output_filename): """Encodes the input data with reed-solomon error correction in 223 byte blocks, and outputs each block along with 32 parity bytes to a new file by the given filename. input is a file-like object The outputted image will be in png format, and will be 255 by x pixels with one color channel. X is the number of 255 byte blocks from the input. Each block of data will be one row, therefore, the data can be recovered if no more than 16 pixels per row are altered. """ coder = rs.RSCoder(255, 223) output = [] while True: block = input.read(223) if not block: break code = coder.encode(block) output.append(code) sys.stderr.write(".") sys.stderr.write("\n") out = Image.new("L", (rowstride, len(output))) out.putdata("".join(output)) out.save(output_filename)
def rs_decode(cc_bits, n, k, **kwargs): byte_len = 8 coder = rs.RSCoder(n, k) # determine number of codewords that have been passed given an RS(n,k) # encoder numWords = len(cc_bits) / n / byte_len # de-interleave if ('intlv' in kwargs): intlv = kwargs['intlv'] else: intlv = np.arange(len(cc_bits)) cc_bits_deintlv = np.zeros(cc_bits.shape, dtype='uint8') cc_bits_deintlv[intlv] = cc_bits.astype('uint8') # convert to decimal cc_dec = co.bin2dec(cc_bits_deintlv, byte_len) # convert to str cc_str = co.dec2char(cc_dec) # reshape uncoded decimal in case you can't decode cc_dec = np.array(cc_dec).reshape(-1, n) # Pre-Allocate ii_str = [] ii_dec = [] for x in range(numWords): ii_str.append([]) ii_dec.append([]) ii_str[x] = ('\x00', '\x00') # Try-Catch (use RS built in checker) for x in range(numWords): thisMsg = cc_str[x * n:(x + 1) * n] # Will this message get decoded? if coder.check_fast(thisMsg): ii_str[x] = coder.decode_fast(thisMsg, nostrip=True) ii_dec[x] = co.char2dec(ii_str[x][0]) # Left Pad with zeros (punctured RS -- expected by decoder) missZero = k - len(ii_dec[x]) ii_dec[x] = np.concatenate( (ii_dec[x], np.zeros(missZero))).astype('uint8') else: # Just truncate the uncoded decimal values (right most k bytes) ii_dec[x] = cc_dec[x][-k:].astype('uint8') ii_bits = np.array([ list(co.dec2bin(ii_dec[x], byte_len).astype('uint8')) for x in range(numWords) ]) ii_bits = np.reshape(ii_bits, (byte_len * k * numWords, )) # return ii_bits, ii_dec, ii_dec_old, cc_bits_deintlv, cc_dec, cc_str, ii_str return ii_bits
def check_rs(ctx): n = 255 k = 223 #u = Z.swig_unsafe.opa_wrapper_swig.CReedSolomon(8,16,112,11,0,4,0,1) gamma_pw, chk_pw = 11, 112 u = Z.swig_unsafe.opa_wrapper_swig.CReedSolomon(8,16,gamma_pw,chk_pw,0,1,0,1) Z.np.random.seed(1) import unireedsolomon as urs pr_gf2= m.cvar.PR_GF2 px =m.cvar.PR_GF2.import_base(0x187) gf_256 = m.GF_q_u32(m.cvar.GF2, px) assert gf_256.is_prim_elem(gf_256.theta()) gf_256.set_prim_elem(gf_256.theta()) rs = m.RSCode_u32(gf_256, n, k); gamma = gf_256.faste(gf_256.theta(), gamma_pw) rs.advanced_init(gf_256.theta(), chk_pw) pr_gf26 = m.PolyRing_Poly_u32(gf_256) rs2 = urs.RSCoder(n, k, generator=2, prim=0x187) data = Z.os.urandom(k) data = b'a'*k tb = [] for x in data: tb.append(gf_256.import_base(x)) c = bytes(map(ord, rs2.encode(data[::-1]))) cc = rs.encode(m.v_poly_u32(tb)) ccx = bytearray(map(gf_256.export_base, list(cc))) #ccx[0] = 0 #ccx[1] = 1 ccx[-1] = 1 ccx[-2] = 1 ccx[-3] = 1 cc = m.v_poly_u32(list(map(gf_256.import_base, ccx))) m2 = bytes(map(gf_256.export_base, rs.decode(cc))) res, mx = u.Decode(ccx[::-1]) print(res) print(u.CorrectableErrorsInFrame()) print(u.UncorrectableErrorsInFrame()) print(mx) print(m2) print(pr_gf2.export_base(gf_256.getModPoly())) return print(rs.g()) print(rs.w().str()) print(rs.g().str()) for x in rs.g().to_vec(): print(pr_gf2.export_base(x))
def unicode_to_reed_solomon(message, number_of_errors): """ converts unicode to dna using reed solomon algorithm :param message: String :param number_of_errors: int :return: String """ encoder = rs.RSCoder(len(message) + (2 * number_of_errors), len(message)) encoded_unicode = encoder.encode(message) return convert_unicode_to_dna(encoded_unicode, 4)
def __init__(self, block_size=0, block_content=0, allow_partial_block=False): """ Create R.S. Code with given block size and given max message (content) length (block_content < block_size; corrects at most (block_content - block_size) / 2 errors) If allow_partial_block is set, then the last block may be made smaller to fit text size. """ self.block_size = block_size or config.RS_BLOCK_SIZE self.block_content = block_content or config.RS_BLOCK_CONTENT self.coder = rs.RSCoder(self.block_size, self.block_content) self.allow_partial_block = allow_partial_block
def convert_reed_solomon_to_binary(encoded_input, message_length, errors): """ converts encoded string input of specified length with predetermined number of possible errors to unicode :param encoded_input: String :param message_length: int :param errors: int :return: String """ rsc = unireedsolomon.RSCoder(message_length + (2 * errors), message_length) return rsc.decode(encoded_input)[0]
def convert_binary_to_reed_solomon(binary_input, errors): """ converts binary string input, using errors, to DNA using reed solomon algorithm :param binary_input: String :param errors: int :return: String """ rsc = unireedsolomon.RSCoder( len(binary_input) + (2 * errors), len(binary_input)) return rsc.encode(binary_input)
def reed_solomon_to_unicode(dna, message_length, number_of_errors): """ converts DNA string, encoded using reed solomon, into unicode string :param dna: String :param message_length: int :param number_of_errors: int :return: String """ decoder = rs.RSCoder(message_length + (2 * number_of_errors), message_length) dna_string = convert_dna_to_unicode(dna, 4) return decoder.decode(dna_string)[0]
def create_cout_encoder(n1, k1, k2): # Description: Create [n1 X k1] GF(2**k2) matrix # Input: # n1 - Rows number # k1 - Columns number # k2 - log(q), q - alphabet size # Output: # A random [n1 X k1] binary matrix with prob of entry being 1 is 1 / (10 * d) generator = 3 poly = rs.find_prime_polynomials(generator, k2, single=True) coder = rs.RSCoder(n1, k1, generator, poly, 1, k2) return coder
def decode(self, bitarr): if not bitarr: print('warning: empty block received') return output = [] if not self.allow_partial_block and len(bitarr) % (self.block_size * 8): # cut off unaligned bitarr = bitarr[:-(len(bitarr) % (self.block_size * 8))] if self.allow_partial_block: bitarr_tr = bitarr else: bitarr_tr = _transpose(bitarr, nblocks=self.block_size) bitarr_bytes = _bitarr2bytes(bitarr_tr, False) fail = False for op in range(3): fail = False for i in range(0, len(bitarr_bytes), self.block_size): try: enc_bytes = bitarr_bytes[i:i + self.block_size] if self.allow_partial_block and len( enc_bytes) < self.block_size: partial_block_coder = rs.RSCoder( len(enc_bytes), len(enc_bytes) // 2) decoded = partial_block_coder.decode(enc_bytes)[0] else: decoded = self.coder.decode(enc_bytes)[0] if len(decoded) < self.block_content: diff = self.block_content - len(decoded) decoded = '\0' * diff + decoded #print('d', _str2bitarr(decoded)) output.extend(_str2bitarr(decoded)) except: fail = True output.extend( _bytes2bitarr(bitarr_bytes[i:i + self.block_content])) if not fail: break # hardcoded off-by-one fixes if op == 0: # try adding a byte at beginning bitarr_bytes = b'\0' + bitarr_bytes elif op == 1: # try deleting a byte at end bitarr_bytes = bitarr_bytes[1:-1] return _unpad(output)
def read_sample(self, timestamp): """ Returns the data array of the specific file. Parameters ---------- time : str Specific file name for an array of spectrometer data at a certain time. This will be formatted as [name].[file extension] Returns ------- data : list A 2 by 3648 data array from the spectrometer (wavelength, intensity) """ file_name = str(timestamp).replace(",", "_") + ".bin" f = (self.samples_directory_path / file_name).open("rb") output_data = f.read() if len(output_data) == oasis_config.TOTAL_SPECTROMETER_FILE_SIZE: # data is encoded decoder = rs.RSCoder(oasis_config.TOTAL_SPECTROMETER_FILE_SIZE, oasis_config.SPECTROMETER_DATA_SIZE) # Latin-1 encoding turns the string into a bytes stream that can be written. # Default "encode" uses utf-8, which "wraps around" anything above \x80 or 128 bit, which mutates the data # ASCII encode does even worse, it just throws an error if you give it any data above \x80. # I've checked to make sure latin-1 encodes by turning string to byte stream without changing the data at all: # Anything from \x00 to \xff WILL map 1-to-1 and onto to the right place. output_data = decoder.decode(output_data)[0].encode("latin-1") else: #data was not encoded output_data = output_data.encode("latin-1") print("Warning: data was not encrypted, data size " + str(len(output_data)) + ", expected data size " + str(oasis_config.TOTAL_SPECTROMETER_FILE_SIZE)) output = [[], []] for x in range(oasis_config.SPECTROMETER_PIXEL_NUMBER): output[0].append(struct.unpack("f", output_data[:4])) output_data = output_data[4:] for x in range(oasis_config.SPECTROMETER_PIXEL_NUMBER): output[1].append(struct.unpack("f", output_data[:4])) output_data = output_data[4:] return output
def decode(input_filename): coder = rs.RSCoder(255, 223) input = Image.open(input_filename) data = "".join(chr(x) for x in input.getdata()) del input blocknum = 0 while True: if blocknum * 255 > len(data): break rowdata = data[blocknum * 255:(blocknum + 1) * 255] decoded = coder.decode(rowdata) blocknum += 1 sys.stdout.write(str(decoded)) sys.stderr.write(".") sys.stderr.write("\n")
def __init__(self, file_name): State_Machine.__init__(self) self.state = State.SCREEN_DETECTION self.byte_sequence = collections.deque() self.packet_count = 0 self.last_data_packet = None self.receiver_ack = True self.rs_coder = unireedsolomon.RSCoder(Constants.RS_codeword_size, Constants.RS_message_size) if Constants.SIMULATE: simulation_handler = Constants.SIMULATION_HANDLER self.cv_handler = simulation_handler.tmtr self.cap = simulation_handler.tmtr logging.info('Initialized snd at state ' + str(self.state)) self._load_file(file_name)
def rsCode(): message = request.args.get("message") noErrors = request.args.get("noErrors") coder = rs.RSCoder(len(message) + int(noErrors), len(message)) encodedText = coder.encode(message) myBytes = encodedText.encode("utf-8") data = bitarray(bin(int(myBytes.hex(), base=16))[2:]) code = binStringFromBitArr(data) response = make_response( jsonify({"code": code}), 200, ) response.headers["Content-Type"] = "application/json" return response
def __init__(self): State_Machine.__init__(self) self.state = State.SCREEN_DETECTION self.data_packet = np.array self.decoded_packet_count = 0 self.decoded_sequence = collections.deque() self.bitCount = 0 self.screen_mask = None self.rs_coder = unireedsolomon.RSCoder(Constants.RS_codeword_size, Constants.RS_message_size) if Constants.SIMULATE: simulation_handler = Constants.SIMULATION_HANDLER self.cv_handler = simulation_handler.rcvr self.cap = simulation_handler.rcvr print('Initialized rcvr at state ' + str(self.state)) time.sleep(1)
def save_sample(self, timestamp, data): """ After the spectrometer finishes sampling, it will send the data to this function to be saved. Parameters ---------- timestamp : str A string of current linux time to be formatted [timestamp].[file extension] data : list A 2 by 3648 data array containing the recorded data from the spectrometer (wavelength, intensity) """ # TODO: other numbers for failure to save file (for debugging purposes) file_name = str(timestamp).replace( ".", "_") + ".bin" # Get the filename from the timestamp and extension f = (self.samples_directory_path / file_name).open("wb") write_byte_stream = b"" for i in range(len(data)): for j in range(len(data[i])): data[i][j] = bytes(struct.pack("f", data[i][j])) write_byte_stream = write_byte_stream + data[i][j] encoder = rs.RSCoder(oasis_config.TOTAL_SPECTROMETER_FILE_SIZE, oasis_config.SPECTROMETER_DATA_SIZE) if not len(write_byte_stream) == oasis_config.SPECTROMETER_DATA_SIZE: # Just no encoding if we can't get a match. Hopefully the SD card doesn't act up. print("Error: expected spectrometer data size is " + str(oasis_config.SPECTROMETER_DATA_SIZE) + ", but actual data size is " + str(len(write_byte_stream))) else: # Latin-1 encoding turns the string into a bytes stream that can be written. # Default "encode" uses utf-8, which "wraps around" anything above \x80 or 128 bit, which mutates the data # ASCII encode does even worse, it just throws an error if you give it any data above \x80. # I've checked to make sure latin-1 encodes by turning string to byte stream without changing the data at all: # Anything from \x00 to \xff WILL map 1-to-1 and onto to the right place. write_byte_stream = encoder.encode(write_byte_stream).encode( 'latin-1') f.write(write_byte_stream) # pickle.dump(data, f) # This writes the data f.close() return
def rsDeocde(): code = request.args.get("code") noErrors = request.args.get("noErrors") messageLength = request.args.get("messageLength") coder = rs.RSCoder(int(messageLength) + int(noErrors), int(messageLength)) message = "" finalMessage = "" try: #message = binStringFromBitArr(decode(bitarray(code))) message = bytes.fromhex(hex(int(code, 2))[2:]).decode() finalMessage = coder.decode(message)[0] except ValueError as e: if str(e) == "Two errors detected.": finalMessage = "I can detect upto, but not correct, two errors." response = make_response( jsonify({"message": finalMessage}), 200, ) response.headers["Content-Type"] = "application/json" return response
def encode(self, bitarr): output = [] if self.allow_partial_block: bitarr_bytes = _bitarr2bytes(bitarr, 8) else: bitarr_bytes = _bitarr2bytes(bitarr, self.block_content * 8) #print('e', len(bitarr_bytes)) for i in range(0, len(bitarr_bytes), self.block_content): print(i) input_bytes = bitarr_bytes[i:i + self.block_content] if self.allow_partial_block and len( input_bytes) * 2 < self.block_content: partial_block_size = len(input_bytes) * 2 partial_block_coder = rs.RSCoder(partial_block_size, len(input_bytes)) encoded = partial_block_coder.encode(input_bytes) else: encoded = self.coder.encode(input_bytes) output.extend(_str2bitarr(encoded)) if not self.allow_partial_block: output_tr = _transpose(output, blocksz=self.block_size) else: output_tr = output return output_tr
import unireedsolomon as rs coder = rs.RSCoder(10, 9)
def check_rs(ctx): n = 255 k = 223 Z.np.random.seed(1) import unireedsolomon as urs pr_gf2 = m.cvar.PR_GF2 px = m.cvar.PR_GF2.import_base(0x11b) rs2 = urs.RSCoder(n, k, generator=3) gf_256 = m.GF_q_u32(m.cvar.GF2, 8) print(pr_gf2.export_base(gf_256.getModPoly())) return x = gf_256._import(pr_gf2.x()) g3 = m.cvar.PR_GF2.import_base(3) gf_256.set_prim_elem(g3) pr_gf26 = m.PolyRing_Poly_u32(gf_256) rs = m.RSCode_u32(gf_256, n, k) print(rs.g()) print(rs.w().str()) print(rs.g().str()) for x in rs.g().to_vec(): print(pr_gf2.export_base(x)) print(rs2.g[k]) lsb = 1 # fixed, need to be consistent with pack_vector_ for ntest in range(10): data = tuple(Z.np.random.randint(2, size=k * 8).tolist()) m1 = m.pack_vector_gfq_u32(gf_256, m.v_u32(data)) data_byte = bytes(Z.Format(data).bin2byte(lsb=lsb).v) v = bytes([0] * (n - k)) + data_byte tb = [] for x in v: tb.append(gf_256.import_base(x)) print(len(tb)) mprime = m.v_poly_u32(tb) mprime = pr_gf26._import(mprime) b = pr_gf26.mod(mprime, rs.g()) u = pr_gf26.add(mprime, b) print(pr_gf2.export_base(u.get_safe(0)), pr_gf2.export_base(u.get_safe(32)), pr_gf2.export_base(u.get_safe(254))) #lsb ^= 1 c2_byte = rs2.encode(data_byte[::-1]) c2_byte = bytes(map(ord, c2_byte)) print(c2_byte) print(data_byte[0], data_byte[-1]) m1 = m.pack_vector_gfq_u32(gf_256, m.v_u32(data)) c = rs.encode(m1) print(pr_gf2.export_base(c[0]), pr_gf2.export_base(c[-1])) c1 = list(m.unpack_vector_gfq_u32(gf_256, c)) c1_byte = bytes(Z.Format(c1).bin2byte(lsb=lsb).v) #c1_byte = c1_byte[n-k:] + c1_byte[:n-k] print(c2_byte[::-1] == c1_byte) print(data_byte[0], data_byte[-1]) return cx = m.unpack_vector_gfq_u32(gf_256, c) cx = list(cx) c2 = m.pack_vector_gfq_u32(gf_256, cx) mm = rs.decode(c2)
def reed_solomon_to_unicode(dna, message_length, number_of_errors): decoder = rs.RSCoder(message_length + (2 * number_of_errors), message_length) dna_string = convert_dna_to_unicode(dna, 4) return decoder.decode(dna_string)[0]
def unicode_to_reed_solomon(message, number_of_errors): encoder = rs.RSCoder(len(message) + (2 * number_of_errors), len(message)) encoded_unicode = encoder.encode(message) return convert_unicode_to_dna(encoded_unicode, 4)
def convert_reed_solomon_to_binary(encoded_input, message_length, errors): rsc = unireedsolomon.RSCoder(message_length + (2 * errors), message_length) return rsc.decode(encoded_input)[0]
def convert_binary_to_reed_solomon(binary_input, errors): rsc = unireedsolomon.RSCoder( len(binary_input) + (2 * errors), len(binary_input)) return rsc.encode(binary_input)
from io import BytesIO import re, time, base64 import pickle #-------------------------face recognition and encryption----------------------------- import face_recognition import random import numpy as np import unireedsolomon as rs import os from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.backends import default_backend #FUNCTIONS #reed solomon coder RS = rs.RSCoder(128, 90) #encryption function def encrypt(key): backend = default_backend() #Padding key to 32 bytes k = randIntTo32(key) #Initalisation Vector iv = os.urandom(16) #saving iv ivFile = open("HelloFlask/static/encryption_folder/ivFile", 'wb') pickle.dump(iv, ivFile) ivFile.close()