Beispiel #1
0
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_fast(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)
Beispiel #2
0
def rs_encode_image(image_file, code_word_num):
    with open(image_file, 'rb') as f:
        image_contain = f.read()
    k = ceil(len(image_contain) / float(PACKET_SIZE))
    n = 2**ceil(log(k) / log(2))
    fout = open(IMAGE + '.rs', 'wb')
    mat = []
    for i in range(k):
        if (len(image_contain) > (i + 1) * PACKET_SIZE):
            mat.append([
                str(ii) for ii in list(image_contain[i * PACKET_SIZE:(i + 1) *
                                                     PACKET_SIZE])
            ])
        else:
            empty = ['0' for ii in range(PACKET_SIZE)]
            empty[:(len(image_contain) - i * PACKET_SIZE)] = list(
                image_contain[i * PACKET_SIZE:len(image_contain)])
            mat.append(empty)
    for i in range(n - k):
        mat.append(['0' for ii in range(PACKET_SIZE)])
    mat_arr_orig = np.array(mat)
    mat_arr_code = mat_arr_orig

    coder = rs.RSCoder(n, k)
    for i in range(PACKET_SIZE):
        code_word = list(
            coder.encode(bytes([int(ii) for ii in mat_arr_orig[:k, i]])))
        mat_arr_code[:, i] = code_word

    for line in mat_arr_code:
        fout.write(bytes(''.join(list(line)), encoding='utf-8'))
    fout.close()

    return mat_arr_orig, image_contain, mat, mat_arr_code
Beispiel #3
0
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]
        if not rowdata: break

        decoded = coder.decode_fast(rowdata)

        blocknum += 1
        sys.stdout.write(str(decoded))
        sys.stderr.write(".")
    sys.stderr.write("\n")
Beispiel #4
0
def computeId(ids, erasure):
    def fromStr(a):
        return [ord(x) for x in a]

    def toStr(a):
        return ''.join([str(chr(x)) for x in a])

    # Compared to libfec:
    # (python) generator 3 maps to prim 13 in libfec
    # (python) fcr 1 maps to  fcr 19 in libfec
    # found after exhaustive search...
    #
    # The rest is similar: gfpoly=0x25, symbolsize=2^5, 20 symbols per block,
    # i.e., 12 parity and 8 data (encoding a 40bit id).

    coder = rs.RSCoder(20, 8, 3, 0x25, 1, 5)
    print 'Number of erasures: {0}'.format(len(erasure))
    try:
        corrected, ecc = coder.decode(toStr(ids),
                                      k=8,
                                      nostrip=True,
                                      erasures_pos=erasure)
        ecc = fromStr(ecc)
        corrected = fromStr(corrected)
        print corrected, ecc
        all = corrected + ecc
        if not coder.check(toStr(all)):
            print 'Cannot validate ecc'
            return None
        else:
            result = 0
            for i, x in enumerate(corrected):
                result = result + x
                if i < len(corrected) - 1:
                    result = result * 32  # 2^5
            return result
    except Exception as inst:
        print 'Cannot recover id: ', inst
        return None
#uint32 omzetten naar uint8
encoded_msg_bit = util.uint32_to_bit(encoded_msg)
encoded_msg_8uint = util.bit_to_uint8(encoded_msg_bit)
uint8_stream = np.array(encoded_msg, dtype=np.uint8)
# ====================== CHANNEL ENCODING ========================
# ======================== Reed-Solomon ==========================
print("-------START CHANNEL ENCODING-------")
initiele_lengte = len(uint8_stream)
print("ingang channel encoder:", uint8_stream)
# as we are working with symbols of 8 bits
# choose n such that m is divisable by 8 when n=2^m−1
# Example: 255 + 1 = 2^m -> m = 8
n = 255  # code_word_length in symbols
k = 223  # message_length in symbols

coder = rs.RSCoder(n, k)

# generate a matrix with k rows (for each message)
uint8_stream.resize((math.ceil(len(uint8_stream) / k), k), refcheck=False)
# afterwards you can iterate over each row to encode the message
messages = uint8_stream

rs_encoded_message = StringIO()

for message in messages:
    code = coder.encode_fast(message, return_string=True)
    rs_encoded_message.write(code)

# TODO What is the RSCoder outputting? Convert to a uint8 (byte) stream before putting it over the channel
rs_encoded_message_uint8 = np.array(
    [ord(c) for c in rs_encoded_message.getvalue()], dtype=np.uint8)
def rs_decode_image(rs_data):
    # with open(rs_file, 'rb') as f:
        # rs_contain = f.read()
    n, k, s, rs_contain = n_k_s_from_image(rs_data)
    packet_size = int(s)

    # out_file_name = os.path.basename(rs_data)
    # out_file_dir = os.path.dirname(rs_data)
    # out_name = os.path.join(out_file_dir, out_file_name[:-3].replace(".jpg", "_re.jpg"))

    # fout = open(out_name, 'wb')
    # print("re image save : {}".format(out_name))

    mat = []
    for i in range(n):
        if(len(rs_contain) >= (i+1) * packet_size):
            if six.PY3:
                mat_temp = list(rs_contain[i * packet_size: (i+1) * packet_size])
            else:
                mat_temp = [ord(ii) for ii in list(rs_contain[i * packet_size: (i+1) * packet_size])]
            mat.append(mat_temp)
        else:
            empty = [0 for ii in range(packet_size)]
            if len(rs_contain) > (i+1) * packet_size:
                if six.PY3:
                    empty[:(len(rs_contain) - i * packet_size)] = \
                            list(rs_contain[i * packet_size: len(rs_contain)])
                else:
                    empty[:(len(rs_contain) - i * packet_size)] = \
                            [ord(ii) for ii in list(rs_contain[i * packet_size: len(rs_contain)])]

            mat.append(empty)
    mat_arr_code = np.array(mat)            
    mat_arr_orig = mat_arr_code[:k, :]

    coder = rs.RSCoder(n, k)
    for i in range(packet_size):
        code_word = b''.join(struct.pack("B", ii) for ii in mat_arr_code[:, i]) # bytes
        source = coder.decode(code_word)[0] # list str
        source = [ii for ii in source]
        if len(source) < k:
            mat_arr_orig[0:(k-len(source)), i] = [0 for ii in range(k-len(source))]
            mat_arr_orig[(k-len(source)):, i] = [ord(ii) for ii in source]
        else:
            mat_arr_orig[:, i] = [ord(ii) for ii in source]
    
    out_image_contain = b''
    
    # out_bytes = b''.join([struct.pack("B", ii) for ii in mat_arr_orig[0, 4:]])
    # fout.write(out_bytes)
    # for line in mat_arr_orig[1:, :]:
    for line in mat_arr_orig[:, :]:
        out_bytes = b''.join([struct.pack("B", ii) for ii in list(line)])
        out_image_contain += out_bytes

    print('RS decode done!')
    #     fout.write(out_bytes)
    # fout.close()


    # pic = plt.imread(out_name)
    # plt.imshow(pic)
    # plt.axis('off')
    # plt.show()

    return out_image_contain
def rs_encode_image(image_data, packet_size):
    '''
    读取文件,按 packet_size大小划分为待编码块
    按行排列,
    按纵向进行RS编码,增加冗余的编码数据块

                  packet_size 
    -------------------------------------------
    | |              图像文件                 |
RS  -------------------------------------------
    | |              图像文件                 |
    -------------------------------------------
编  | |              图像文件                 |
    -------------------------------------------
    | |              图像文件                 |
码  -------------------------------------------
    | |              图像文件                 |
    -------------------------------------------
块  |*|**************冗余编码*****************|
    -------------------------------------------
    |*|**************冗余编码*****************|
    -------------------------------------------

    '''
    n, k, s, image_contain = n_k_s_to_image(image_data, packet_size)
    # with open(image_file, 'rb') as f:
        # image_contain = f.read()
    #k = 9
    #n = 16
    print(k, n)
    # output_rs_file = image_file + '.rs'
    # fout = open(output_rs_file, 'wb')
    mat = []
    for i in range(k):
        if(len(image_contain) > (i+1) * packet_size):
            if six.PY3:
                mat_temp = list(image_contain[i * packet_size: (i+1) * packet_size])
            else:
                mat_temp = [ord(ii) for ii in list(image_contain[i * packet_size: (i+1) * packet_size])]
            mat.append(mat_temp)
        else:                                                         # 处理最后一个packet
            empty = [0 for ii in range(packet_size)]
            if six.PY3:
                empty[:(len(image_contain) - i * packet_size)] = \
                    list(image_contain[i * packet_size: len(image_contain)])
            else:
                empty[:(len(image_contain) - i * packet_size)] = \
                    [ord(ii) for ii in list(image_contain[i * packet_size: len(image_contain)])]
            mat.append(empty)                                                # mat[] = [, , , , ]

    for i in range(n-k):
        mat.append([0 for ii in range(packet_size)])

    mat_arr_orig = np.array(mat)
    mat_arr_code = mat_arr_orig

    coder = rs.RSCoder(n, k)

    for i in range(packet_size):
        #  source = bytes([int(ii) for ii in mat_arr_orig[:k, i]])
        source = ''.join([chr(ii) for ii in mat_arr_orig[:k, i]])                # str
        code_word = list(coder.encode(source))                                  # string list
        mat_arr_code[:, i] = [ord(ii) for ii in code_word]                                       # 按列进行编码

    out_image_contain = b''
    for line in mat_arr_code:                                                                   # 按行输出
        if six.PY3:
            # print(list(line))
            out_bytes = b''.join([struct.pack("B", ii) for ii in list(line)])
        elif six.PY2:
            # print(list(line))
            out_bytes = b''.join([struct.pack("B", int(ii)) for ii in list(line)])

        out_image_contain += out_bytes
    #     fout.write(out_bytes)
    # fout.close()

    return out_image_contain
Beispiel #8
0
def rs_decode_image(rs_file, recv_packet):
    # with open(rs_file, 'rb') as f:
    # rs_contain = f.read()
    n, k, s, rs_contain = n_k_s_from_image(rs_file)
    errpos = count_errpos(recv_packet, n)
    print("errpos is : {}".format(errpos))
    packet_size = int(s)

    out_file_name = os.path.basename(rs_file)
    out_file_dir = os.path.dirname(rs_file)
    out_name = os.path.join(out_file_dir,
                            out_file_name[:-3].replace(".jpg", "_re.jpg"))

    fout = open(out_name, 'wb')
    print("re image save : {}".format(out_name))

    mat = []
    for i in range(n):
        if (len(rs_contain) >= (i + 1) * packet_size):
            if six.PY3:
                mat_temp = list(rs_contain[i * packet_size:(i + 1) *
                                           packet_size])
            else:
                mat_temp = [
                    ord(ii) for ii in list(rs_contain[i * packet_size:(i + 1) *
                                                      packet_size])
                ]
            mat.append(mat_temp)
        else:
            empty = [0 for ii in range(packet_size)]
            if len(rs_contain) > i * packet_size:
                if six.PY3:
                    empty[:(len(rs_contain) - i * packet_size)] = \
                            list(rs_contain[i * packet_size: len(rs_contain)])
                else:
                    empty[:(len(rs_contain) - i * packet_size)] = \
                            [ord(ii) for ii in list(rs_contain[i * packet_size: len(rs_contain)])]

            mat.append(empty)
    mat_arr_code = np.array(mat)
    mat_arr_orig = mat_arr_code[:k, :]
    print("mat code is:")
    print(mat_arr_code)
    print("size of mat code is:")
    print(mat_arr_code.shape)

    coder = rs.RSCoder(n, k)
    try:
        for i in range(packet_size):
            code_word = b''.join(
                struct.pack("B", ii) for ii in mat_arr_code[:, i])  # bytes
            source = coder.decode(code_word,
                                  erasures_pos=errpos)[0]  # list str
            source = [ii for ii in source]
            if len(source) < k:
                mat_arr_orig[0:(k - len(source)),
                             i] = [0 for ii in range(k - len(source))]
                mat_arr_orig[(k - len(source)):,
                             i] = [ord(ii) for ii in source]
            else:
                mat_arr_orig[:, i] = [ord(ii) for ii in source]
    except Exception, e:
        print(e.message)