Exemple #1
0
    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)
Exemple #2
0
 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
Exemple #3
0
    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')
Exemple #4
0
 def decode(self, input):
     return zlib.decompress(_bitarr2bytes(input, pad=False)).decode('ascii')
Exemple #5
0
 def encode(self, bitarr):
     output = []
     bitarr_bytes = _bitarr2bytes(bitarr, 8, 8)
     encoded = self.coder.encode(bitarr_bytes)
     output = _bytes2bitarr(encoded)
     return output