def test_prim_fcr_long(self): nn = 48 kk = 34 tt = nn - kk rs = RSCodec(tt, fcr=120, prim=0x187) hexencmsg = '08faa123555555c000000354064432c0280e1b4d090cfc04887400' \ '000003500000000e1985ff9c6b33066ca9f43d12e8' strf = str if sys.version_info[0] >= 3 else unicode encmsg = bytearray.fromhex(strf(hexencmsg)) decmsg = encmsg[:kk] tem = rs.encode(decmsg) self.assertEqual(encmsg, tem, msg="encoded does not match expected") tdm = rs.decode(tem) self.assertEqual(tdm, decmsg, msg="decoded does not match original") tem1 = bytearray(tem) numerrs = tt >> 1 for i in sample(range(nn), numerrs): tem1[i] ^= 0xff tdm = rs.decode(tem1) self.assertEqual(tdm, decmsg, msg="decoded with errors does not match original") tem1 = bytearray(tem) numerrs += 1 for i in sample(range(nn), numerrs): tem1[i] ^= 0xff self.assertRaises(ReedSolomonError, rs.decode, tem1)
def test_prim_fcr_basic(self): nn = 30 kk = 18 tt = nn - kk rs = RSCodec(tt, fcr=120, prim=0x187) hexencmsg = '00faa123555555c000000354064432c02800fe97c434e1ff5365' \ 'cf8fafe4' strf = str if sys.version_info[0] >= 3 else unicode encmsg = bytearray.fromhex(strf(hexencmsg)) decmsg = encmsg[:kk] tem = rs.encode(decmsg) self.assertEqual(encmsg, tem, msg="encoded does not match expected") tdm = rs.decode(tem) self.assertEqual(tdm, decmsg, msg="decoded does not match original") tem1 = bytearray(tem) # clone a copy # encoding and decoding intact message seem OK, so test errors numerrs = tt >> 1 # inject tt/2 errors (expected to recover fully) for i in sample(range(nn), numerrs): # inject errors in random places tem1[i] ^= 0xff # flip all 8 bits tdm = rs.decode(tem1) self.assertEqual(tdm, decmsg, msg="decoded with errors does not match original") tem1 = bytearray(tem) # clone another copy numerrs += 1 # inject tt/2 + 1 errors (expected to fail and detect it) for i in sample(range(nn), numerrs): # inject errors in random places tem1[i] ^= 0xff # flip all 8 bits # if this fails, it means excessive errors not detected self.assertRaises(ReedSolomonError, rs.decode, tem1)
def test_long(self): rs = RSCodec(10) msg = bytearray("a" * 10000, "utf8") enc = rs.encode(msg) dec = rs.decode(enc) self.assertEqual(dec, msg) enc[177] = 99 enc[2212] = 88 dec2 = rs.decode(enc) self.assertEqual(dec2, msg)
def test_correction(self): rs = RSCodec(10) msg = bytearray("hello world " * 10, "utf8") enc = rs.encode(msg) self.assertEqual(rs.decode(enc), msg) for i in [27, -3, -9, 7, 0]: enc[i] = 99 self.assertEqual(rs.decode(enc), msg) enc[82] = 99 self.assertRaises(ReedSolomonError, rs.decode, enc)
def test_correction(self): rs = RSCodec(10) msg = bytearray("hello world " * 10, "utf8") enc = rs.encode(msg) self.assertEqual(rs.decode(enc), msg) for i in [27, -3, -9, 7, 0]: enc[i] = 99 self.assertEqual(rs.decode(enc), msg) enc[82] = 99 self.assertRaises(ReedSolomonError, rs.decode, enc)
def test_long(self): rs = RSCodec(10) msg = bytearray("a" * 10000, "utf8") enc = rs.encode(msg) dec = rs.decode(enc) self.assertEqual(dec, msg) enc[177] = 99 enc[2212] = 88 dec2 = rs.decode(enc) self.assertEqual(dec2, msg)
def reed_solomon_decode(txt: typing.Union[bytes, str, bytearray], number_repair_symbols: int = 2) -> bytes: global rscodec, number_r_symbols if rscodec is None or number_r_symbols != number_repair_symbols: rscodec = RSCodec(number_repair_symbols) number_r_symbols = number_repair_symbols return bytes(rscodec.decode(txt))
def decode(quart_coded_data): quart_coded_data = quart_coded_data[4:-4:] binary_coded_data = '' for byte in quart_coded_data: if byte == '0': binary_coded_data += '00' elif byte == '1': binary_coded_data += '01' elif byte == '2': binary_coded_data += '10' elif byte == '3': binary_coded_data += '11' else: raise ValueError coded_data = [] for bit_chunk in range(0, len(binary_coded_data), 8): chunk_data = '' for bit_ind in range(8): chunk_data += binary_coded_data[bit_chunk + bit_ind] value = int(chunk_data, 2) coded_data.append(value) coded_data = bytes(coded_data) rsc = RSCodec(10) decoded_data = rsc.decode(coded_data)[0].decode() return decoded_data
def listen_linux(frame_rate=44100, interval=0.1): mic = alsaaudio.PCM(alsaaudio.PCM_CAPTURE, alsaaudio.PCM_NORMAL, device="default") mic.setchannels(1) mic.setrate(44100) mic.setformat(alsaaudio.PCM_FORMAT_S16_LE) num_frames = int(round((interval / 2) * frame_rate)) mic.setperiodsize(num_frames) print("start...") in_packet = False packet = [] while True: l, data = mic.read() if not l: continue chunk = np.fromstring(data, dtype=np.int16) dom = dominant(frame_rate, chunk) if in_packet and match(dom, HANDSHAKE_END_HZ): byte_stream = extract_packet(packet) try: byte_stream = RSCodec(FEC_BYTES).decode(byte_stream) byte_stream = byte_stream.decode("utf-8") #print(byte_stream) if "201502091" in byte_stream: # remove studentId new_byteStream = byte_stream.replace('201502091 ', '').strip() display(new_byteStream) #print(new_byteStream) #print(type(new_byteStream) new_byteStream = RSCodec(FEC_BYTES).encode(new_byteStream) #print(type(new_byteStream))--> bytearray play(new_byteStream) # call main function #new_byteStream = new_byteStream.encode("utf-8") #new_byteStream = RSCodec(FEC_BYTES).encode(new_byteStream) except ReedSolomonError as e: pass #print("{}: {}".format(e, byte_stream)) packet = [] in_packet = False elif in_packet: packet.append(dom) elif match(dom, HANDSHAKE_START_HZ): in_packet = True
class ReedSolomonDecoder: def __init__(self, file="logo.jpg"): self.decodeMap: typing.Dict[int, bytes] = {} self.file: str = file self.rscodec: typing.Optional[RSCodec] = None def decodeFolder(self): for file in os.listdir(self.file): if file.endswith(".RS"): with open(os.path.join(self.file, file), "rb") as f: data = f.read() i, data = self.decode(data) self.decodeMap[i] = data with open(self.file + ".DECODED", "wb") as f: for key in sorted(self.decodeMap): f.write(self.decodeMap[key]) def decode(self, text) -> typing.Tuple[int, bytes]: norepair_symbols: bytes = xor_mask(struct.unpack("<I", text[:4])[0]) text = text[4:] if self.rscodec is None: self.rscodec = RSCodec(int(norepair_symbols)) decoded = self.rscodec.decode(text) i: int = struct.unpack("<I", decoded[:4])[0] i: int = xor_mask(i) data: bytes = decoded[4:] return i, data @staticmethod def get_file_size(file) -> int: return os.stat(file).st_size
def extract_packet(freqs): # listen_linux 함수에서 쓰임 freqs = freqs[::2] ## 2개씩 끊어서 가져옴 bit_chunks = [int(round((f - START_HZ) / STEP_HZ)) for f in freqs] bit_chunks = [c for c in bit_chunks[1:] if 0 <= c < (2**BITS)] byte_stream = bytearray(decode_bitchunks(BITS, bit_chunks)) try: byte_stream = RSCodec(FEC_BYTES).decode(byte_stream) byte_stream = byte_stream.decode("utf-8") if "201502049" in byte_stream: except_byte_stream = byte_stream.replace("201502049", "") del freqs[20:-8] with noalsaerr(): p = pyaudio.PyAudio() stream = p.open(format=pyaudio.paFloat32, channels=1, rate=44100, output=True) for freq in freqs: samples = (np.sin(2 * np.pi * np.arange(44100 * 0.4) * freq / 44100)).astype(np.float32) stream.write(samples) stream.stop_stream() stream.close() p.terminate() except ReedSolomonError as e: #pass print("{}: {}".format(e, byte_stream)) return except_byte_stream
def decodeWithReedSolo(encodedata): if len(encodedata) > 255: return b'', False, 255 # print(encodedata) # if len(encodedata) > 255: # c = math.ceil(len(encodedata) / 2) # print(c) # if c > 255: # c = 255 # byte2, check2, err2 = decodeWithReedSolo(encodedata[c:]) # byte1, check1, err1 = decodeWithReedSolo(encodedata[:c]) # if (check2[0] and check1[0]): # print(check2) # return byte1 + byte2, check1, err1 + err2 # else: # ecc_len = math.ceil(len(encodedata) / (1+errorPercent) * errorPercent) # return b'', False, ecc_len // 2 + 1 ecc_len = math.ceil(len(encodedata) / (1 + errorPercent) * errorPercent) # print(ecc_len) rsc = RSCodec(math.ceil(ecc_len)) check = rsc.check(encodedata) try: decoded_msg, decoded_msgecc, errata_pos = rsc.decode(encodedata) check = rsc.check(decoded_msgecc) return decoded_msg, check, len(errata_pos) except: return b'', check, ecc_len // 2 + 1
def rsdecode(rscode, msglen): ''' msg:rs二进制码 ''' ecc = RSCodec(96) length = len(rscode) padmsglen = (msglen // 7 + 1) * 7 rslen = padmsglen + 96 * 8 temp = [] for i in range(0, padmsglen, 7): temp.append(int(rscode[i:i + 7], 2)) for i in range(padmsglen, rslen, 8): temp.append(int(rscode[i:i + 8], 2)) temp = bytearray(temp) try: rscode = ecc.decode(temp) rscode = ''.join(format(x, '08b') for x in rscode) finally: if len(rscode) == length: print('too many bits errors!') return rscode[:msglen] else: temp = '' for i in range(0, padmsglen // 7 * 8, 8): temp += rscode[i + 1:i + 8] return temp[:msglen]
class TMDecoder: def __init__(self): self.rsc = RSCodec(ECC) def decode_to_bytes(self, data): frames = data.split(ASM) decoded_frames = [] for frame in frames: decoded_frame = self.rsc.decode(frame)[0] decoded_frames.append(decoded_frame) return b''.join(decoded_frames) def decode_to_tc_datalink_packets(self, data): i = 0 frames = [] spacecraft_id = None data_bytes = self.decode_to_bytes(data) while i < len(data_bytes): frame_header = TransferFramePrimaryHeader.parse( data_bytes[i:i + FRAME_PRIMARY_HEADER_BYTES]) if spacecraft_id == None: spacecraft_id = frame_header.spacecraft_id else: if frame_header.spacecraft_id != spacecraft_id: # If there is trailing noise at the end of the signal return frames frame_length = frame_header.frame_length + 1 frame = data_bytes[i:i + frame_length] i += frame_length frames.append(TCDataLinkPacket.from_bytes(frame)) return frames def unconvolve_code(self, data): pass
def recover(phrase, k=12, mnemonic=Mnemonic("english")): """Attempts to recover the original mnemonic phrase from a mnemonic phrase with errors. Infers the value of n from the number of words in the phrase. If words are missing or unknown, include an arbitrary character in its place. (e.g. '_') Arguments: phrase (str): Mnemonic phrase with errors to fix. k (int): Number of words chosen at random. mnemonic (Mnemonic): Instance of Mnemonic to use. """ symbols = mnemonic_to_symbols(phrase, mnemonic) ok, error = validate_n_k(len(symbols), k) if not ok: raise ValueError(error) coder = RSCodec(nsize=len(symbols), nsym=(len(symbols)-k), c_exp=BIP39_SYMBOL_SIZE) erasures = [i for i, s in enumerate(symbols) if s < 0] recovered, _, _ = coder.decode(symbols, erase_pos=erasures) coded = coder.encode(recovered) phrase = symbols_to_mnemonic(coded, mnemonic) if not mnemonic.check(phrase): raise ValueError("error-corrected phrase does not have a valid checksum") return phrase
def listen_linux(frame_rate=44100, interval=0.1): mic = alsaaudio.PCM(alsaaudio.PCM_CAPTURE, alsaaudio.PCM_NORMAL, device="default") mic.setchannels(1) mic.setrate(44100) mic.setformat(alsaaudio.PCM_FORMAT_S16_LE) num_frames = int(round((interval / 2) * frame_rate)) mic.setperiodsize(num_frames) print("start...") in_packet = False packet = [] while True: l, data = mic.read() if not l: continue chunk = np.fromstring(data, dtype=np.int16) dom = dominant(frame_rate, chunk) #print(dom) if in_packet and match(dom, HANDSHAKE_END_HZ): byte_stream = extract_packet(packet) try: byte_stream = RSCodec(FEC_BYTES).decode(byte_stream) byte_stream = byte_stream.decode("utf-8") #print(byte_stream) #이 부분을 찍어보면 최종 문자열을 확인가능 if "201502127" in byte_stream: # in 키워드를 이용하면 문자열이 있는지를 찾을 수 있다. ID_count = byte_stream.count( "201502127") #201502127이 몇번 출현하는지 찾는다. byte_stream = extract_Data(byte_stream, ID_count) display(byte_stream) try: byte_stream = RSCodec(FEC_BYTES).encode( byte_stream.encode("utf-8") ) # 필요한 데이터 뒤에 오류 코드까지 아스키 코드(1byte)로 인코딩 되어 나온다. #print(byte_stream[0:4]) #byteArray가 된 " hel"이 출력됨. sound(bytes_to_freq(byte_stream)) except ReedSolomonError as e: pass #print("{}: {}".format(e, byte_stream)) except ReedSolomonError as e: pass #print("{}: {}".format(e, byte_stream)) packet = [] in_packet = False elif in_packet: packet.append(dom) elif match(dom, HANDSHAKE_START_HZ): in_packet = True
class Receiver: def __init__(self, decode_method, bits_per_packet): self.msg = [] self.decode_method = decode_method self.bits_per_packet = bits_per_packet self.rsc = RSCodec(SALOMON_DEPTH) def receive_packet(self, packet): if self.decode_method == TRIPLE: self._decode_triple_packet(packet) elif self.decode_method == HAMMING: self._decode_hamming_packet(packet) elif self.decode_method == SALOMON: self._decode_salomon_packet(packet) def _decode_triple_packet(self, packet): for i in range(0, len(packet), MULTIPLIER): zero = 0 one = 0 for j in range(3): if packet[i + j] == 0: zero += 1 elif packet[i + j] == 1: one += 1 else: raise if zero > one: self.msg.append(0) else: self.msg.append(1) def _decode_hamming_packet(self, packet): number = ImageBitParser.bit_array_to_number(packet) decoded_packet = [ int(bit) for bit in hamming_codec.decode(number, len(packet)) ] self.msg += decoded_packet def _decode_salomon_packet(self, packet): decoded_packet = [bit for bit in packet[:self.bits_per_packet]] packet = packet[self.bits_per_packet:] for i in range(0, len(packet), 8): bit_array = [ packet[i], packet[i + 1], packet[i + 2], packet[i + 3], packet[i + 4], packet[i + 5], packet[i + 6], packet[i + 7] ] number = ImageBitParser.bit_array_to_number(bit_array) decoded_packet.append(number) try: decoded_packet = self.rsc.decode(bytearray(decoded_packet)) except Exception: decoded_packet = [decoded_packet[:self.bits_per_packet]] decoded_packet = [bit for bit in decoded_packet[0]] self.msg += decoded_packet
def remove_reed5(self, s1,missing_pack_list): rsc = RSCodec(self.NUMBER_OF_ERRORS) try: s2 = rsc.decode(s1,erase_pos=missing_pack_list) return (s2[0]) except: return (None)
def decode(msg): for i in range(1,81): try: rs=RSCodec(80-i) x=rs.decode(msg) return x except: pass return "UNREADABLE"
def decode(compressed, coding): #correct errors if coding!=0 if(coding): rs = RSCodec(coding) compressed = rs.decode(compressed) #decompress the bytes in_bytes = zlib.decompress(compressed) #decode the text in bytes string = in_bytes.decode("utf-8") return string
def listen_linux(frame_rate=44100, interval=0.1): mic = alsaaudio.PCM(alsaaudio.PCM_CAPTURE, alsaaudio.PCM_NORMAL, device="default") mic.setchannels(1) mic.setrate(44100) mic.setformat(alsaaudio.PCM_FORMAT_S16_LE) num_frames = int(round((interval / 2) * frame_rate)) mic.setperiodsize(num_frames) print("start...") in_packet = False packet = [] while True: l, data = mic.read() if not l: continue chunk = np.fromstring(data, dtype=np.int16) dom = dominant(frame_rate, chunk) #소리를 주파수로 변환하는 함수(dominant), 소리에 맞게 주파수를 분리 if in_packet and match(dom, HANDSHAKE_END_HZ): #끝 주파수를 수신함 byte_stream = extract_packet( packet) #주파수의 묶음을 데이터로 바꿔줌(extract packet) try: byte_stream = RSCodec(FEC_BYTES).decode( byte_stream) #RSCodec 함수로 FEC_BYTES 디코딩 byte_stream = byte_stream.decode("utf-8") #문자값으로로 디코딩 #print(byte_stream) if byte_stream[:9] == number: #학번이 입력되면 #print(byte_stream[:9]) display(byte_stream[9:]) #학번 이후부터 결과출력 byte_stream = byte_stream[9:] # print(byte_stream[9:]) byte_stream = byte_stream.encode("utf-8") #아스키코드값으로 인코딩 byte_stream = RSCodec(FEC_BYTES).encode( byte_stream) #RSCodec 함수로 FEC_BYTES 인코딩 make_sound(byte_stream) #make_sound함수 호출 except ReedSolomonError as e: pass #print("{}: {}".format(e, byte_stream)) packet = [] in_packet = False elif in_packet: packet.append(dom) #주파수를 받음 elif match(dom, HANDSHAKE_START_HZ): in_packet = True
class RSCode: """ Reed-Solomon encoder and decoder """ def __init__(self, num_ec=None): """ Create R.S. Code with given number of EC symbols. corrects num_ec / 2 errors. """ self.num_ec = num_ec or config.RS_NUM_EC self.coder = RSCodec(self.num_ec) def encode(self, bitarr): output = [] bitarr_bytes = _bitarr2bytes(bitarr, 8, 8) encoded = self.coder.encode(bitarr_bytes) output = _bytes2bitarr(encoded) return output def decode(self, bitarr, starts_to_try=10): if not bitarr: print('warning: empty block received') return # sometimes we have extra bytes at the beginning, fix that by bruteforcing for offs in range(starts_to_try): try: if len(bitarr) % 8: # cut off unaligned bitarr_trim = bitarr[:-len(bitarr) % 8] else: bitarr_trim = bitarr if config.DEBUG: import os.path decoded = bitarr_trim[:] if os.path.exists('_actual_message.npy'): if offs: print('reed-solomon offset =', offs) actual = np.load('_actual_message.npy') while len(decoded) > len(actual): decoded.pop() while len(decoded) < len(actual): decoded.append(0) Y = np.array(decoded) X = np.array(actual) bitwise_errs = np.sum(np.abs(Y - X)) X = X.reshape(-1, 8) Y = Y.reshape(-1, 8) errs = np.sum(np.any(X != Y, axis=1)) #print(X) #print(Y) print('bit errors', bitwise_errs, '=', bitwise_errs / len(decoded)) print('byte errors', errs, '=', errs / (len(decoded) // 8)) bitarr_bytes = _bitarr2bytes(bitarr_trim, None) decoded = self.coder.decode(bitarr_bytes)[0] output = _bytes2bitarr(decoded) return _unpad(output, 8) except: bitarr = bitarr[8:] raise Exception('FATAL: reed-solomon decoding failed')
def listen_linux(frame_rate=44100, interval=0.1): mic = alsaaudio.PCM(alsaaudio.PCM_CAPTURE, alsaaudio.PCM_NORMAL) mic.setchannels(1) mic.setrate(44100) mic.setformat(alsaaudio.PCM_FORMAT_S16_LE) num_frames = int(round((interval / 2) * frame_rate)) mic.setperiodsize(num_frames) print("start...") in_packet = False packet = [] while True: l, data = mic.read() if not l: continue chunk = np.fromstring(data, dtype=np.int16) dom = dominant(frame_rate, chunk) if in_packet and match(dom, HANDSHAKE_END_HZ): byte_stream = extract_packet(packet) print("original code", byte_stream) if match_num(byte_stream) == False: break try: byte_stream = RSCodec(FEC_BYTES).decode(byte_stream) byte_stream = byte_stream.decode("utf-8") print(byte_stream) byte_stream = byte_stream.replace("201702087", "") display(byte_stream) display("") sin_freq = [] byte_stream = byte_stream.encode("utf-8") byte_stream = RSCodec(FEC_BYTES).encode(byte_stream) sin_freq = make_freq(byte_stream, sin_freq) print(sin_freq) make_sound(sin_freq) except ReedSolomonError as e: print("{}: {}".format(e, byte_stream)) packet = [] in_packet = False elif in_packet: packet.append(dom) elif match(dom, HANDSHAKE_START_HZ): in_packet = True
def listen_linux(frame_rate=44100, interval=0.1): mic = alsaaudio.PCM(alsaaudio.PCM_CAPTURE, alsaaudio.PCM_NORMAL, device="default") mic.setchannels(1) mic.setrate(44100) mic.setformat(alsaaudio.PCM_FORMAT_S16_LE) num_frames = int(round((interval / 2) * frame_rate)) mic.setperiodsize(num_frames) print("start...") in_packet = False packet = [] while True: l, data = mic.read() if not l: continue chunk = np.fromstring(data, dtype=np.int16) dom = dominant(frame_rate, chunk) if in_packet and match(dom, HANDSHAKE_END_HZ): bit_chunks, byte_stream = extract_packet(packet) try: byte_stream = RSCodec(FEC_BYTES).decode(byte_stream) byte_stream = byte_stream.decode("utf-8") try: index = byte_stream.index("201502007") except: index = -1 if (index > -1): stream = bit_chunks[0:index * 2] + bit_chunks[index * 2 + 18:-8] rs = [] for target in RSCodec(4).encode(byte_stream[0:index] + byte_stream[index + 9:])[-4:]: rs.append(int(target / 16)) rs.append(target & 15) stream = [12] + stream + rs + [20] make_sounds(stream) display(byte_stream) except ReedSolomonError as e: pass # print("{}: {}".format(e, byte_stream)) packet = [] in_packet = False elif in_packet: packet.append(dom) elif match(dom, HANDSHAKE_START_HZ): in_packet = True
class PublicCode: def __init__(self): self.n = 78 * 768 self.inner_code = RSCodec(78 - 32) self.outer_code = ReedMuller(6) def encode(self, msg): return self.outer_code.encode(self.inner_code.encode(msg)) def decode(self, msg): return self.inner_code.decode(self.outer_code.decode(msg))
def listen_linux(frame_rate=44100, interval=0.1): mic = alsaaudio.PCM(alsaaudio.PCM_CAPTURE, alsaaudio.PCM_NORMAL, device="default") mic.setchannels(1) mic.setrate(44100) mic.setformat(alsaaudio.PCM_FORMAT_S16_LE) num_frames = int(round((interval / 2) * frame_rate)) mic.setperiodsize(num_frames) print("start...") in_packet = False packet = [] while True: l, data = mic.read() if not l: continue chunk = np.fromstring(data, dtype=np.int16) dom = dominant(frame_rate, chunk) if in_packet and match(dom, HANDSHAKE_END_HZ): byte_stream = extract_packet(packet) #print("packet: ",packet) try: byte_stream = RSCodec(FEC_BYTES).decode(byte_stream) byte_stream_test = byte_stream.decode("utf-8") if '201402455' in byte_stream_test: byte_stream = re.sub(b'201402455',b''0,byte_stream) byte_stream = RSCodec(FEC_BYTES).encode(byte_stream) temp_stream = [] temp_stream.append(HANDSHAKE_START_HZ) temp_stream.append(HANDSHAKE_START_HZ) for i in range(len(byte_stream)): temp_stream.append(((byte_stream[i] >> 4)*STEP_HZ)+START_HZ) temp_stream.append(((byte_stream[i] & 0xf)*STEP_HZ)+START_HZ) temp_stream.append(HANDSHAKE_END_HZ) temp_stream.append(HANDSHAKE_END_HZ) p = pyaudio.PyAudio() stream = p.open(format=pyaudio.paFloat32, channels=1, rate =44100, output = True) duration = 0.5 # for i in range(len(n:ewbyte_stream)): samples = (np.sin(2*np.pi*np.arange(44100*duration)*(temp_stream[i]/44100))).astype(np.float32) stream.write(samples) stream.stop_stream() stream.close() p.terminate() else: print("don't have my_number")
def _unhead(self, hh: bytes): _rrs = RSCodec() try: hd = _rrs.decode(hh)[0] except: print('broken header') hd = hh[:-10] if hd[:5] != b'FsTeg': raise Exception('Unknown header type') ll = 1 + int.from_bytes(hd[8:12], 'little') * \ self.block_size // _rsc_block return ll
def listen_linux(frame_rate=44100, interval=0.1): mic = alsaaudio.PCM(alsaaudio.PCM_CAPTURE, alsaaudio.PCM_NORMAL) mic.setchannels(1) mic.setrate(44100) mic.setformat(alsaaudio.PCM_FORMAT_S16_LE) num_frames = int(round((interval / 2) * frame_rate)) mic.setperiodsize(num_frames) print("start...") in_packet = False ch_next = False packet = [] while True: l, data = mic.read() if not l: continue chunk = np.fromstring( data, dtype=np.int16) #convert voice to bit with each tone dom = dominant(frame_rate, chunk) #Fourier Transfer: back to original #print(dom); #print(dom) if in_packet and ch_next and dom < 1000: #abs(HAND - dom) packet.pop() byte_stream = extract_packet(packet) print("original code", byte_stream) try: # check errors byte_stream = RSCodec(FEC_BYTES).decode( byte_stream) # reed solo byte_stream = byte_stream.decode("utf-8") display(byte_stream) display("") except ReedSolomonError as e: print("{}: {}".format(e, byte_stream)) packet = [] in_packet = False ch_next = False elif in_packet: packet.append(dom) if match(dom, HANDSHAKE_END_HZ): ch_next = True elif match(dom, HANDSHAKE_START_HZ): in_packet = True
def listen_linux(frame_rate=44100, interval=0.1): mic = alsaaudio.PCM(alsaaudio.PCM_CAPTURE, alsaaudio.PCM_NORMAL, device="default") mic.setchannels(1) mic.setrate(44100) mic.setformat(alsaaudio.PCM_FORMAT_S16_LE) num_frames = int(round((interval / 2) * frame_rate)) mic.setperiodsize(num_frames) print("start...") in_packet = False packet = [] while True: l, data = mic.read() if not l: continue chunk = np.fromstring(data, dtype=np.int16) dom = dominant(frame_rate, chunk) #print(dom) if in_packet and match(dom, HANDSHAKE_END_HZ): byte_stream = extract_packet(packet) try: byte_stream = RSCodec(FEC_BYTES).decode(byte_stream) byte_stream = byte_stream.decode("utf-8") # change to str to use find(), replace() byte_stream = str(byte_stream) # check student number if (byte_stream.find("201502111") != -1): # delete student number byte_stream = byte_stream.replace("201502111", "") display(byte_stream) display("") # play sound without student number play_linux(byte_stream, interval) except ReedSolomonError as e: print("{}: {}".format(e, byte_stream)) packet = [] in_packet = False elif in_packet: packet.append(dom) elif match(dom, HANDSHAKE_START_HZ): in_packet = True
def listen_linux(frame_rate=44100, interval=0.1): HANDSHAKE_START_HZ = 8192 HANDSHAKE_END_HZ = HANDSHAKE_START_HZ + 512 mic = alsaaudio.PCM(alsaaudio.PCM_CAPTURE, alsaaudio.PCM_NORMAL) mic.setchannels(1) mic.setrate(44100) mic.setformat(alsaaudio.PCM_FORMAT_S16_LE) #2 num_frames = int(round((interval / 2) * frame_rate)) mic.setperiodsize(num_frames) print("start...") in_packet = False packet = [] coeff = 0 while True: l, data = mic.read() #nyquist 2*bandwidth*log2(L) if not l: continue chunk = np.fromstring(data, dtype=np.int16) dom = dominant(frame_rate, chunk) #print(dom) #print(HANDSHAKE_START_HZ) #print(dom) if in_packet and match(dom, HANDSHAKE_END_HZ): #print(packet) byte_stream = extract_packet(packet) #print(byte_stream) print("original code", byte_stream) try: byte_stream = RSCodec(FEC_BYTES).decode(byte_stream) byte_stream = byte_stream.decode("utf-8") display(byte_stream) display("") except ReedSolomonError as e: print("{}: {}".format(e, byte_stream)) packet = [] in_packet = False elif in_packet: packet.append(dom) elif match(dom, HANDSHAKE_START_HZ): in_packet = True
def dna_reed_solomon_decode(txt: typing.Union[bytes, str, bytearray], number_repair_symbols: int = 2, c_exp: int = 2, prim_poly: int = 7) -> bytes: """ Warning: dna_reed_solomon_* requires a custom RSCodec version with support for custom c_exp and nsize. """ tmp_rscodec = RSCodec(number_repair_symbols, c_exp=c_exp, prim=prim_poly, nsize=2**c_exp - 1) decoded: bytearray = tmp_rscodec.decode(txt) return bytes(bits_to_bytes(decoded))
def listen_linux(frame_rate=44100, interval=0.1): mic = alsaaudio.PCM(alsaaudio.PCM_CAPTURE, alsaaudio.PCM_NORMAL, device="default") mic.setchannels(1) mic.setrate(44100) mic.setformat(alsaaudio.PCM_FORMAT_S16_LE) num_frames = int(round((interval / 2) * frame_rate)) mic.setperiodsize(num_frames) print("start...") in_packet = False packet = [] while True: l, data = mic.read() if not l: continue chunk = np.fromstring(data, dtype=np.int16) dom = dominant(frame_rate, chunk) #if packet!=[]: #print("this is final pac : ", packet[-1]) #print("this is now : ", dom) if in_packet and match(dom, HANDSHAKE_END_HZ): if not match(packet[-1], 3840): packet.append(dom) continue byte_stream = extract_packet(packet) #print(byte_stream) try: byte_stream = RSCodec(FEC_BYTES).decode(byte_stream) byte_stream = byte_stream.decode("utf-8") display(byte_stream) except ReedSolomonError as e: pass print("{}: {}".format(e, byte_stream)) packet = [] in_packet = False elif in_packet: packet.append(dom) elif match(dom, HANDSHAKE_START_HZ): in_packet = True
def listen_linux(frame_rate=44100, interval=0.1): mic = alsaaudio.PCM(alsaaudio.PCM_CAPTURE, alsaaudio.PCM_NORMAL, device="default") mic.setchannels(1) mic.setrate(44100) mic.setformat(alsaaudio.PCM_FORMAT_S16_LE) num_frames = int(round((interval / 2) * frame_rate)) mic.setperiodsize(num_frames) print("start...") in_packet = False packet = [] while True: l, data = mic.read() if not l: continue chunk = np.fromstring(data, dtype=np.int16) dom = dominant(frame_rate, chunk) if in_packet and match(dom, HANDSHAKE_END_HZ): byte_stream = extract_packet(packet) try: byte_stream = RSCodec(FEC_BYTES).decode(byte_stream) byte_stream = byte_stream.decode("utf-8") if ID in byte_stream: global result_stream #print(byte_stream) result_stream = byte_stream.replace(ID, '') result_stream = result_stream.strip() rs = RSCodec(4) result_stream = rs.encode(result_stream) print(result_stream) play_linux() display(byte_stream) except ReedSolomonError as e: pass #print("{}: {}".format(e, byte_stream)) packet = [] in_packet = False elif in_packet: packet.append(dom) elif match(dom, HANDSHAKE_START_HZ): in_packet = True
def listen_linux(frame_rate=44100, interval=0.1): mic = alsaaudio.PCM(alsaaudio.PCM_CAPTURE, alsaaudio.PCM_NORMAL, device="default") mic.setchannels(1) mic.setrate(44100) mic.setformat(alsaaudio.PCM_FORMAT_S16_LE) num_frames = int(round((interval / 2) * frame_rate)) mic.setperiodsize(num_frames) print("start...") in_packet = False packet = [] while True: l, data = mic.read() if not l: continue chunk = np.fromstring(data, dtype=np.int16) dom = dominant(frame_rate, chunk) if in_packet and match(dom, HANDSHAKE_END_HZ): byte_stream, real_output = extract_packet(packet) try: byte_stream = RSCodec(FEC_BYTES).decode(byte_stream) byte_stream = byte_stream.decode("utf-8") if byte_stream.find("201604148") != -1: byte_stream = byte_stream.replace("201604148", "",1) stream_len = len(byte_stream) stream_len -=1 display(byte_stream) real_output = real_output[0:stream_len*2] make_sound(real_output) else: pass except ReedSolomonError as e: pass #print("{}: {}".format(e, byte_stream)) packet = [] in_packet = False elif in_packet: packet.append(dom) elif match(dom, HANDSHAKE_START_HZ): in_packet = True
def demodul(data,size): assert(size % 7 != 0) ''' ret = bytearray(size) ndata = bytearray(data) idx = (-7) % size for i in range(size - 1,-1,-1): for j in range(8): ret[i] = (ret[i] << 1) | (ndata[idx] & 1) ndata[idx] = (ndata[idx] >> 1) idx = (idx - 7) % size ''' rsc = RSCodec(size - 43) try: ret = rsc.decode(data) except: ret = None return ret
def slimdecode(frame, config): rs = RSCodec(config["trame"]["ecc"]["length"]) frame = rs.decode(frame) cs = frame.pop() if cs != functools.reduce(operator.xor, frame): print("Checksum failed") return False frame.pop(0) # Stripping start byte out = [] for fmt in config["sensors"]: l = struct.calcsize(fmt) val, = struct.unpack("!" + fmt, frame[:l]) frame = frame[l:] out.append(val) print(len(frame)) return out
class Watermarker(object): def __init__(self, max_payload, ec_bytes, seed = 1895746671, mother = "bior3.1", sparsity = 0.7): self.mother = mother self.sparsity = sparsity self.rscodec = RSCodec(ec_bytes) self.max_payload = max_payload self.total_bits = (max_payload + ec_bytes) * 8 self.seed = seed @classmethod def _interleave(cls, cH, cV, cD): vec = numpy.zeros(cH.size + cV.size + cD.size, dtype = float) vec[0::3] = cH.ravel() vec[1::3] = cV.ravel() vec[2::3] = cD.ravel() return vec @classmethod def _deinterleave(cls, vec, cH, cV, cD): return vec[0::3].reshape(cH.shape), vec[1::3].reshape(cV.shape), vec[2::3].reshape(cD.shape) def _generate_sequences(self, chunk_size): rand = Random(self.seed) seq0 = numpy.array([int(rand.random() >= self.sparsity) for _ in range(chunk_size)]) seq1 = seq0[::-1] return seq0, seq1 def _embed(self, img, payload, k): cA, (cH, cV, cD) = dwt2(img.astype(float), self.mother) vec = self._interleave(cH, cV, cD) chunk_size = vec.size // self.total_bits sequences = self._generate_sequences(chunk_size) for i, bit in enumerate(iterbits(payload)): offset = i * chunk_size vec[offset : offset + chunk_size] += k * sequences[bit] #vec[i : self.total_bits*chunk_size : self.total_bits] += k * sequences[bit] w, h = img.shape cH2, cV2, cD2 = self._deinterleave(vec, cH, cV, cD) return idwt2((cA, (cH2, cV2, cD2)), self.mother)[:w,:h] def embed(self, img, payload, k = 4, rescale_color = True): if len(payload) > self.max_payload: raise ValueError("payload too long") padded = bytearray(payload) + b"\x00" * (self.max_payload - len(payload)) encoded = self.rscodec.encode(padded) if img.ndim == 2: output = self._embed(img, encoded, k) elif img.ndim == 3: output = numpy.zeros(img.shape, dtype=float) for i in range(img.shape[2]): output[:,:,i] = self._embed(img[:,:,i], encoded, k) else: raise TypeError("img must be a 2d or 3d array") if rescale_color: output = rescale_intensity(output, out_range = (numpy.min(img), numpy.max(img))) return output def _extract(self, img): cA, (cH, cV, cD) = dwt2(img.astype(float), self.mother) vec = self._interleave(cH, cV, cD) chunk_size = vec.size // self.total_bits seq0, seq1 = self._generate_sequences(chunk_size) byte = 0 output = bytearray() for i in range(self.total_bits): offset = i * chunk_size chunk = vec[offset: offset + chunk_size] #chunk = vec[i:self.total_bits*chunk_size:self.total_bits] corr0, _ = pearsonr(chunk, seq0) corr1, _ = pearsonr(chunk, seq1) bit = int(corr1 > corr0) byte = (byte << 1) | bit if i % 8 == 7: output.append(byte) byte = 0 return output def _try_decode(self, payload): try: return self.rscodec.decode(payload) except ReedSolomonError: rpayload = bytearray(b ^ 255 for b in payload) return self.rscodec.decode(rpayload) def extract(self, img): if img.ndim == 2: return self._try_decode(self._extract(img)) elif img.ndim == 3: for i in range(img.shape[2]): try: return self._try_decode(self._extract(img[:,:,i])) except ReedSolomonError: pass return self._try_decode(self._extract(mean(img, 2))) else: raise TypeError("img must be a 2d or 3d array")
def test_simple(self): rs = RSCodec(10) msg = bytearray("hello world " * 10, "utf8") enc = rs.encode(msg) dec = rs.decode(enc) self.assertEqual(dec, msg)
class Watermarker(object): EPSILON = 0.001 def __init__(self, max_payload, ec_bytes, seed = 1910819922, mother = "haar"): self.mother = mother self.rscodec = RSCodec(ec_bytes) self.max_payload = max_payload self.total_bits = (max_payload + ec_bytes) * 8 rand = Random(seed) chunk_size = 50000 self.seq0 = numpy.array([int(rand.random() > 0.7) for _ in range(chunk_size)]) self.seq1 = numpy.array(self.seq0[::-1]) #while True: # self.seq0 = numpy.array([int(rand.random() > 0.8) for _ in range(chunk_size)]) # self.seq1 = numpy.array([int(rand.random() > 0.75) for _ in range(chunk_size)]) # corr, _ = pearsonr(self.seq0, self.seq1) # if corr < self.EPSILON: # break def _embed(self, img, payload, k): cA, (cH, cV, cD) = dwt2(img, self.mother) cH2 = cH.reshape(cH.size) cV2 = cV.reshape(cV.size) cD2 = cD.reshape(cD.size) assert cH2.shape == cV2.shape == cD2.shape chunk_size = (cH2.size * 3) // (self.total_bits) sequence_of = (self.seq0[:chunk_size], self.seq1[:chunk_size]) buffers = (cH2, cV2, cD2) for i, bit in enumerate(iterbits(payload)): seq = sequence_of[bit] target = buffers[i % 3] offset = (i//3) * chunk_size target[offset:offset + seq.size] += k * seq w, h = img.shape return idwt2((cA, (cH2.reshape(cH.shape), cV2.reshape(cV.shape), cD2.reshape(cD.shape))), self.mother)[:w,:h] def embed(self, img, payload, k): if len(payload) > self.max_payload: raise ValueError("payload too long") padded = bytearray(payload) + b"\x00" * (self.max_payload - len(payload)) encoded = self.rscodec.encode(padded) if len(img.shape) == 2: return self._embed(img, encoded, k) elif len(img.shape) == 3: output = numpy.zeros(img.shape) for i in range(img.shape[2]): output[:,:,i] = self._embed(img[:,:,i], encoded, k) return output else: raise TypeError("img must be a 2d or 3d array") def _extract(self, img): cA, (cH, cV, cD) = dwt2(img, self.mother) cH2 = cH.reshape(cH.size) cV2 = cV.reshape(cV.size) cD2 = cD.reshape(cD.size) assert cH2.shape == cV2.shape == cD2.shape buffers = (cH2, cV2, cD2) chunk_size = (cH2.size * 3) // (self.total_bits) seq0 = self.seq0[:chunk_size] seq1 = self.seq1[:chunk_size] byte = 0 output = bytearray() for i in range(self.total_bits): target = buffers[i % 3] offset = (i//3) * chunk_size chunk = target[offset : offset + seq0.size] corr0, _ = pearsonr(chunk, seq0) corr1, _ = pearsonr(chunk, seq1) bit = int(corr1 > corr0) byte = (byte << 1) | bit if i % 8 == 7: output.append(byte) byte = 0 #print repr(output) return output def extract(self, img): if len(img.shape) == 2: return self.rscodec.decode(self._extract(img)) elif len(img.shape) == 3: for i in range(img.shape[2]): try: return self.rscodec.decode(self._extract(img[:,:,i])) except ReedSolomonError: pass return self.rscodec.decode(self._extract(mean(img, 2))) else: raise TypeError("img must be a 2d or 3d array")
class Watermarker(object): EPSILON = 0.001 def __init__(self, max_payload, ec_bytes, seed = 1910819922, mother = "haar"): self.mother = mother self.rscodec = RSCodec(ec_bytes) self.max_payload = max_payload self.total_bits = (max_payload + ec_bytes) * 8 rand = Random(seed) chunk_size = 50000 self.seq0 = numpy.array([int(rand.random() > 0.7) for _ in range(chunk_size)]) self.seq1 = numpy.array(self.seq0[::-1]) def _interleave(self, cH, cV, cD): arr = numpy.zeros(cH.size + cV.size + cD.size) sources = [cH.reshape(cH.size), cV.reshape(cV.size), cD.reshape(cD.size)] for i in range(arr.size): src = sources[i % 3] j = i // 3 if j >= src.size: arr = arr[:i] break arr[i] = src[j] return arr def _deinterleave(self, arr, cH, cV, cD): cH2 = numpy.zeros(cH.size) cV2 = numpy.zeros(cV.size) cD2 = numpy.zeros(cD.size) destinations = [cH2, cV2, cD2] for i in range(arr.size): destinations[i % 3][i // 3] = arr[i] return cH2.reshape(cH.shape), cV2.reshape(cV.shape), cD2.reshape(cD.shape) def _embed(self, img, payload, k): cA, (cH, cV, cD) = dwt2(img, self.mother) arr = self._interleave(cH, cV, cD) chunk_size = arr.size // self.total_bits sequence_of = (self.seq0[:chunk_size], self.seq1[:chunk_size]) for i, bit in enumerate(iterbits(payload)): seq = sequence_of[bit] arr[i * chunk_size: i * chunk_size + seq.size] += k * seq w, h = img.shape cH2, cV2, cD2 = self._deinterleave(arr, cH, cV, cD) return idwt2((cA, (cH2, cV2, cD2)), self.mother)[:w,:h] def embed(self, img, payload, k): if len(payload) > self.max_payload: raise ValueError("payload too long") padded = bytearray(payload) + b"\x00" * (self.max_payload - len(payload)) encoded = self.rscodec.encode(padded) if img.ndim == 2: return self._embed(img, encoded, k) elif img.ndim == 3: output = numpy.zeros(img.shape) for i in range(img.shape[2]): output[:,:,i] = self._embed(img[:,:,i], encoded, k) return output else: raise TypeError("img must be a 2d or 3d array") def _extract(self, img): cA, (cH, cV, cD) = dwt2(img, self.mother) arr = self._interleave(cH, cV, cD) chunk_size = arr.size // self.total_bits seq0 = self.seq0[:chunk_size] seq1 = self.seq1[:chunk_size] byte = 0 output = bytearray() for i in range(self.total_bits): chunk = arr[i * chunk_size: i * chunk_size + seq0.size] corr0, _ = pearsonr(chunk, seq0) corr1, _ = pearsonr(chunk, seq1) bit = int(corr1 > corr0) byte = (byte << 1) | bit if i % 8 == 7: output.append(byte) byte = 0 return output def _try_decode(self, payload): try: out = self.rscodec.decode(payload) except ReedSolomonError: #print "!!", repr(payload) try: rpayload = bytearray(b ^ 255 for b in payload) out = self.rscodec.decode(rpayload) except ReedSolomonError: #print "!!", repr(rpayload) out = None return out def extract(self, img): if img.ndim == 2: return self._try_decode(self._extract(img)) elif img.ndim == 3: for i in range(img.shape[2]): out = self._try_decode(self._extract(img[:,:,i])) if out is not None: return out return self._try_decode(self._extract(mean(img, 2))) else: raise TypeError("img must be a 2d or 3d array")
class Watermarker(object): EPSILON = 0.001 def __init__(self, max_payload, ec_bytes, seed = 1910819922, mother = "haar"): self.mother = mother self.rscodec = RSCodec(ec_bytes) self.max_payload = max_payload self.total_bits = (max_payload + ec_bytes) * 8 self.seed = seed def _embed(self, img, payload, k): rand = Random(self.seed) cA, (cH, cV, cD) = dwt2(img, self.mother) cD2 = cD.reshape(cD.size) for bit in iterbits(payload): seq = numpy.array([int(rand.random() > 0.95) for _ in range(cD2.size)]) if bit: cD2 += k * seq return idwt2((cA, (cH, cV, cD2.reshape(cD.shape))), self.mother)[:img.shape[0],:img.shape[1]] def embed(self, img, payload, k): if len(payload) > self.max_payload: raise ValueError("payload too long") payload = bytearray(payload) + "\x00" * (self.max_payload - len(payload)) encoded = self.rscodec.encode(payload) if len(img.shape) == 2: return self._embed(img, encoded, k) elif len(img.shape) == 3: output = numpy.zeros(img.shape) for i in range(img.shape[2]): output[:,:,i] = self._embed(img[:,:,i], encoded, k) return output else: raise TypeError("img must be a 2d or 3d array") def _extract(self, img): rand = Random(self.seed) cA, (cH, cV, cD) = dwt2(img, self.mother) cD2 = cD.reshape(cD.size) byte = 0 output = bytearray() for i in range(self.total_bits): seq = numpy.array([int(rand.random() > 0.95) for _ in range(cD2.size)]) corr, _ = pearsonr(cD2, seq) bit = int(corr > 0.1) byte = (byte << 1) | bit if i % 8 == 7: output.append(byte) byte = 0 print repr(output) return output def extract(self, img): if len(img.shape) == 2: return self.rscodec.decode(self._extract(img)) elif len(img.shape) == 3: for i in range(img.shape[2]): try: return self.rscodec.decode(self._extract(img[:,:,i])) except ReedSolomonError: pass return self.rscodec.decode(self._extract(mean(img, 2))) else: raise TypeError("img must be a 2d or 3d array")
class Watermarker(object): def __init__(self, msg_bytes, ec_bytes, seed, mother = "haar"): self.mother = mother self.rscodec = RSCodec(ec_bytes) self.msg_bytes = msg_bytes self.total_bits = (msg_bytes + ec_bytes) * 8 rand = Random(seed) #self.mask = [rand.randint(0,255) for _ in range(msg_bytes + ec_bytes)] self.mask = [0] * (msg_bytes + ec_bytes) chunk_size = 256*512 // self.total_bits espilon = 0.0001 while True: self.seq0 = numpy.array([int(rand.random() > 0.75) for _ in range(chunk_size)]) self.seq1 = numpy.array([int(rand.random() > 0.7) for _ in range(chunk_size)]) corr, _ = pearsonr(self.seq0, self.seq1) if abs(corr) < espilon: break def _embed(self, img, payload, k): cA, (cH, cV, cD) = dwt2(img, self.mother) w, h = cH.shape cH2 = cH.reshape(cH.size) cV2 = cV.reshape(cV.size) chunk_size = cH2.size // (self.total_bits // 2) assert chunk_size >= self.seq0.size for i, bit in enumerate(iterbits(payload)): dst = (cH2, cV2)[i % 2] seq = (self.seq0, self.seq1)[bit] dst[(i//2)*chunk_size:(i//2)*chunk_size + seq.size] += k * seq return idwt2((cA, (cH2.reshape(w, h), cV2.reshape(w, h), cD)), self.mother)[:img.shape[0],:img.shape[1]] def embed(self, img, payload, k = 10): if len(payload) > self.msg_bytes: raise ValueError("payload too long") if isinstance(payload, str): payload = bytearray(payload) payload.extend([0] * (self.msg_bytes - len(payload))) encoded = self.rscodec.encode(payload) masked = [v ^ m for v, m in zip(encoded, self.mask)] if len(img.shape) == 2: return self._embed(img, masked, k) elif len(img.shape) == 3: res = numpy.zeros(img.shape) for i in range(img.shape[2]): layer = self._embed(img[:,:,i], masked, k) res[:,:,i] = layer return res else: raise TypeError("image must be a 2d or 3d array") def _extract(self, img): cA, (cH, cV, cD) = dwt2(img, self.mother) w, h = cH.shape cH2 = cH.reshape(cH.size) cV2 = cV.reshape(cV.size) chunk_size = cH2.size // (self.total_bits // 2) maskiter = iter(self.mask) payload = bytearray() byte = 0 for i in range(self.total_bits): src = (cH2, cV2)[i % 2] chunk = src[(i//2)*chunk_size:(i//2)*chunk_size + self.seq0.size] corr0, _ = pearsonr(chunk, self.seq0) corr1, _ = pearsonr(chunk, self.seq1) bit = int(corr1 > corr0) byte = bit | (byte << 1) if i % 8 == 7: payload.append(byte ^ maskiter.next()) byte = 0 print repr(payload) return self.rscodec.decode(payload) def extract(self, img): if len(img.shape) == 2: return self._extract(img) elif len(img.shape) == 3: for i in range(img.shape[2]): try: return self._extract(img[:,:,i]) except ReedSolomonError: pass return self._extract(mean(img, 2)) else: raise TypeError("image must be a 2d or 3d array")
class Watermarker(object): def __init__(self, max_payload, ec_bytes, seed = 1895746671, mother = "bior3.1", sparsity = 0.7): self.mother = mother self.sparsity = sparsity self.rscodec = RSCodec(ec_bytes) self.max_payload = max_payload self.total_bits = (max_payload + ec_bytes) * 8 self.seed = seed ''' def _interleave(self, cH, cV, cD): vec = numpy.zeros(cH.size + cV.size + cD.size) rcH = cH.ravel() lH = cH.size rcV = cV.ravel() lV = cH.size + cV.size rcD = cD.ravel() rand = Random(self.seed) indexes = range(vec.size) rand.shuffle(indexes) for i, j in enumerate(indexes): vec[i] = rcD[j - lV] if j >= lV else (rcV[j - lH] if j >= lH else rcH[j]) return vec def _deinterleave(self, vec, cH, cV, cD): cH2 = numpy.zeros(cH.shape) rcH = cH2.ravel() lH = cH.size cV2 = numpy.zeros(cV.shape) rcV = cV2.ravel() lV = cH.size + cV.size cD2 = numpy.zeros(cD.shape) rcD = cD2.ravel() rand = Random(self.seed) indexes = range(vec.size) rand.shuffle(indexes) for i, v in enumerate(vec): j = indexes[i] if j >= lV: rcD[j -lV] = v elif j >= lH: rcV[j - lH] = v else: rcH[j] = v return cH2, cV2, cD2 ''' @classmethod def _interleave(cls, cH, cV, cD): vec = numpy.zeros(cH.size + cV.size + cD.size, dtype = float) vec[0::3] = cH.ravel() vec[1::3] = cV.ravel() vec[2::3] = cD.ravel() return vec @classmethod def _deinterleave(cls, vec, cH, cV, cD): return vec[0::3].reshape(cH.shape), vec[1::3].reshape(cV.shape), vec[2::3].reshape(cD.shape) def _generate_sequences(self, chunk_size): rand = Random(self.seed) seq0 = numpy.array([int(rand.random() >= self.sparsity) for _ in range(chunk_size)]) seq1 = seq0[::-1] return seq0, seq1 def _embed(self, img, payload, k): cA, (cH, cV, cD) = dwt2(img.astype(float), self.mother) vec = self._interleave(cH, cV, cD) chunk_size = vec.size // self.total_bits sequences = self._generate_sequences(chunk_size) for i, bit in enumerate(iterbits(payload)): offset = i * chunk_size vec[offset : offset + chunk_size] += k * sequences[bit] #vec[i:self.total_bits*chunk_size:self.total_bits] += k * sequences[bit] w, h = img.shape cH2, cV2, cD2 = self._deinterleave(vec, cH, cV, cD) return idwt2((cA, (cH2, cV2, cD2)), self.mother)[:w,:h] def embed(self, img, payload, k = 6, tv_denoising_weight = 4, rescale = True): if len(payload) > self.max_payload: raise ValueError("payload too long") padded = bytearray(payload) + b"\x00" * (self.max_payload - len(payload)) encoded = self.rscodec.encode(padded) if img.ndim == 2: output = self._embed(img, encoded, k) elif img.ndim == 3: output = numpy.zeros(img.shape, dtype=float) for i in range(img.shape[2]): output[:,:,i] = self._embed(img[:,:,i], encoded, k) #y, cb, cr = rgb_to_ycbcr(img) #y2 = self._embed(y, encoded, k) #cb = self._embed(cb, encoded, k) #cr = self._embed(cr, encoded, k) #y2 = rescale_intensity(y2, out_range = (numpy.min(y), numpy.max(y))) #Cb2 = rescale_intensity(Cb2, out_range = (numpy.min(Cb), numpy.max(Cb))) #Cr2 = rescale_intensity(Cr2, out_range = (numpy.min(Cr), numpy.max(Cr))) #output = ycbcr_to_rgb(y2, cb, cr) else: raise TypeError("img must be a 2d or 3d array") #if tv_denoising_weight > 0: # output = tv_denoise(output, tv_denoising_weight) if rescale: output = rescale_intensity(output, out_range = (numpy.min(img), numpy.max(img))) #return toimage(output,cmin=0,cmax=255) return output def _extract(self, img): cA, (cH, cV, cD) = dwt2(img.astype(float), self.mother) vec = self._interleave(cH, cV, cD) chunk_size = vec.size // self.total_bits seq0, seq1 = self._generate_sequences(chunk_size) byte = 0 output = bytearray() for i in range(self.total_bits): offset = i * chunk_size chunk = vec[offset: offset + chunk_size] #chunk = vec[i:self.total_bits*chunk_size:self.total_bits] corr0, _ = pearsonr(chunk, seq0) corr1, _ = pearsonr(chunk, seq1) bit = int(corr1 > corr0) byte = (byte << 1) | bit if i % 8 == 7: output.append(byte) byte = 0 return output def _try_decode(self, payload): try: return self.rscodec.decode(payload) except ReedSolomonError: rpayload = bytearray(b ^ 255 for b in payload) return self.rscodec.decode(rpayload) def extract(self, img): if img.ndim == 2: return self._try_decode(self._extract(img)) elif img.ndim == 3: for i in range(img.shape[2]): try: return self._try_decode(self._extract(img[:,:,i])) except ReedSolomonError: pass return self._try_decode(self._extract(mean(img, 2))) else: raise TypeError("img must be a 2d or 3d array")
class Watermarker(object): EPSILON = 0.001 def __init__(self, max_payload, ec_bytes, seed = 1910819922, mother = "haar"): self.mother = mother self.rscodec = RSCodec(ec_bytes) self.max_payload = max_payload self.total_bits = (max_payload + ec_bytes) * 8 rand = Random(seed) chunk_size = 3000 while True: self.seq0 = numpy.array([int(rand.random() > 0.8) for _ in range(chunk_size)]) self.seq1 = numpy.array([int(rand.random() > 0.75) for _ in range(chunk_size)]) corr, _ = pearsonr(self.seq0, self.seq1) if corr < self.EPSILON: break def _embed(self, img, payload, k): cA, (cH, cV, cD) = dwt2(img, self.mother) target = cD.reshape(cD.size) chunk_size = target.size // self.total_bits sequence_of = (self.seq0[:chunk_size], self.seq1[:chunk_size]) for i, bit in enumerate(iterbits(payload)): seq = sequence_of[bit] #chunk = target[i::self.total_bits][:seq.size] chunk = target[i * chunk_size:i * chunk_size + seq.size] chunk += k * seq return idwt2((cA, (cH, cV, target.reshape(cH.shape))), self.mother)[:img.shape[0],:img.shape[1]] def embed(self, img, payload, k): if len(payload) > self.max_payload: raise ValueError("payload too long") payload = bytearray(payload) + "\x00" * (self.max_payload - len(payload)) encoded = self.rscodec.encode(payload) if len(img.shape) == 2: return self._embed(img, encoded, k) elif len(img.shape) == 3: hsv = rgb2hsv(img) i = 0 hsv[:,:,i] = self._embed(hsv[:,:,i], encoded, k) return hsv2rgb(hsv) else: raise TypeError("img must be a 2d or 3d array") def _extract(self, img): cA, (cH, cV, cD) = dwt2(img, self.mother) target = cD.reshape(cD.size) chunk_size = target.size // self.total_bits seq0 = self.seq0[:chunk_size] seq1 = self.seq1[:chunk_size] byte = 0 output = bytearray() for i in range(self.total_bits): chunk = target[i * chunk_size : (i * chunk_size) + seq0.size] #chunk = target[i::self.total_bits][:seq0.size] #if not all(chunk[i] == chunk[i+1] for i in range(chunk.size-1)): corr0, _ = pearsonr(chunk, seq0) corr1, _ = pearsonr(chunk, seq1) bit = int(corr1 > corr0) #else: # bit = 0 byte = (byte << 1) | bit if i % 8 == 7: output.append(byte) byte = 0 print repr(output) return output def extract(self, img): if len(img.shape) == 2: return self.rscodec.decode(self._extract(img)) elif len(img.shape) == 3: hsv = rgb2hsv(img) return self.rscodec.decode(self._extract(hsv[:,:,0])) else: raise TypeError("img must be a 2d or 3d array")