Esempio n. 1
0
def ecc_encode(msg, pad = False):

    """ encode message 'msg' which must be of length MAX_LENGTH:
          
          1. pad msg if 'pad' is True
    
          2. Map each 4bit word of 'msg' to one of the base vectors.

          3. Transpose and repeat message twice.

        The encoding attempts to map nicely to current physical low
        power devices which generally support packet handling and
        where packet lengths are generally limited to 255 bytes (TI:
        CC1101 and CC1120 etc, Freescale RF MCU, HopeRF RFM69W,
        Silicon Labs RF MCU etc). 

    """

    if pad:
        msg = pad(msg)

    length = MAX_LENGTH
    assert len(msg) == length

    div = length / 8

    enc_msg_high = []
    enc_msg_low = []
    for c in msg:
        enc_msg_high.append(BASE_VECTORS[c >> 4])
        enc_msg_low.append(BASE_VECTORS[c % 16])

    ## transpose
    tr_msg_high = bit_transpose(enc_msg_high)
    tr_msg_low = bit_transpose(enc_msg_low)

    ## duplicate
    out = []
    for i in range(8 * 2):
        _from = i * div
        _to = (i+1) * div
        out.extend(tr_msg_high[_from:_to])
        out.extend(tr_msg_high[_from:_to])
        out.extend(tr_msg_low[_from:_to])
        out.extend(tr_msg_low[_from:_to])
    
    return s_to_a(out)
Esempio n. 2
0
def ecc_encode(msg, pad=False):
    """ encode message 'msg' which must be of length MAX_LENGTH:
          
          1. pad msg if 'pad' is True
    
          2. Map each 4bit word of 'msg' to one of the base vectors.

          3. Transpose and repeat message twice.

        The encoding attempts to map nicely to current physical low
        power devices which generally support packet handling and
        where packet lengths are generally limited to 255 bytes (TI:
        CC1101 and CC1120 etc, Freescale RF MCU, HopeRF RFM69W,
        Silicon Labs RF MCU etc). 

    """

    if pad:
        msg = pad(msg)

    length = MAX_LENGTH
    assert len(msg) == length

    div = length / 8

    enc_msg_high = []
    enc_msg_low = []
    for c in msg:
        enc_msg_high.append(BASE_VECTORS[c >> 4])
        enc_msg_low.append(BASE_VECTORS[c % 16])

    ## transpose
    tr_msg_high = bit_transpose(enc_msg_high)
    tr_msg_low = bit_transpose(enc_msg_low)

    ## duplicate
    out = []
    for i in range(8 * 2):
        _from = i * div
        _to = (i + 1) * div
        out.extend(tr_msg_high[_from:_to])
        out.extend(tr_msg_high[_from:_to])
        out.extend(tr_msg_low[_from:_to])
        out.extend(tr_msg_low[_from:_to])

    return s_to_a(out)
Esempio n. 3
0
def test():
    import random

    msg = pad(s_to_a('Hello QuietCasting'))
    assert msg[0] == 18
    assert len(msg) == MAX_LENGTH

    tr_msg = bit_transpose(msg)
    assert reverse_bit_transpose(tr_msg) == msg

    print 'Encoding ...'
    enc = ecc_encode(msg)
    print enc

    print 'Corrupting message (random) ...'
    rec = []
    for c in enc:
        e = 0
        for i in range(8):
            r = random.randint(0, 999)
            if r < 5:
                e |= 1
            e <<= 1
        rec.append(c ^ e)

    total = 0
    for (i, j) in zip(rec, enc):
        if i != j:
            total += 1
    print total, 'corrupted characters detected ...'
    print rec

    print 'Decoding ...'
    dec = ecc_decode(rec)
    print dec
    if dec[1] == msg:
        print 'Decoded succesfully!'
    else:
        print 'Errors detected'
        print dec
        print msg

    print 'Corrupting message (burst) ...'
    rec = array.array('B', [c ^ 255 for c in enc[:24]]) + enc[24:]

    total = 0
    for (i, j) in zip(rec, enc):
        if i != j:
            total += 1
    print total, 'corrupted characters detected ...'
    print rec

    print 'Decoding ...'
    dec = ecc_decode(rec)
    print dec
    if dec[1] == msg:
        print 'Decoded succesfully!'
    else:
        print 'Errors detected'
        print dec
        print msg
Esempio n. 4
0
def ecc_decode(received_code):
    """ decode 'received_code'.

        'received_code' is the set of MAX_LENGTH * 4 bytes making up
        the received packet.

        the optimal decoded message is the one maximizing the
        posterior probability given the received code using Bayes
        rule. An iterative algorithm may be appropriate here but to
        keep things simple we will follow a simpler scheme where we
        just use the reverse map to detect the most probable message
        word.

    """

    length = MAX_LENGTH * 4
    div = MAX_LENGTH / 8

    assert len(received_code) == length

    ## break duplicate data into 2 parts and each part into high bit
    ## and low pit parts

    code_1_high = []
    code_1_low = []
    code_2_high = []
    code_2_low = []
    while received_code:
        (head, received_code) = (received_code[:div], received_code[div:])
        code_1_high.extend(head)
        (head, received_code) = (received_code[:div], received_code[div:])
        code_2_high.extend(head)
        (head, received_code) = (received_code[:div], received_code[div:])
        code_1_low.extend(head)
        (head, received_code) = (received_code[:div], received_code[div:])
        code_2_low.extend(head)

    ## transpose
    tr_code_1_high = reverse_bit_transpose(code_1_high)
    tr_code_1_low = reverse_bit_transpose(code_1_low)
    tr_code_2_high = reverse_bit_transpose(code_2_high)
    tr_code_2_low = reverse_bit_transpose(code_2_low)

    # decode
    dec_code = []
    has_error = False
    for i in range(MAX_LENGTH):
        high1 = REVERSE_MAP[tr_code_1_high[i]]
        low1 = REVERSE_MAP[tr_code_1_low[i]]
        high2 = REVERSE_MAP[tr_code_2_high[i]]
        low2 = REVERSE_MAP[tr_code_2_low[i]]
        c = 0
        ## do high bits
        if high1 < 16 and high2 < 16:
            if high1 == high2:
                c = high1
            else:
                has_error = True

        elif high1 < 16 and high2 == 16:
            c = high1

        elif high1 == 16 and high2 < 16:
            c = high2

        else:
            has_error = True

        c <<= 4

        ## do low bits
        if low1 < 16 and low2 < 16:
            if low1 == low2:
                c |= low1
            else:
                has_error = True

        elif low1 < 16 and low2 == 16:
            c |= low1

        elif low1 == 16 and low2 < 16:
            c |= low2

        else:
            has_error = True

        dec_code.append(c)

    return (has_error, s_to_a(dec_code))
Esempio n. 5
0
def test():
    import random

    msg = pad(s_to_a('Hello QuietCasting'))
    assert msg[0] == 18
    assert len(msg) == MAX_LENGTH

    tr_msg = bit_transpose(msg)
    assert reverse_bit_transpose(tr_msg) == msg

    print 'Encoding ...'
    enc = ecc_encode(msg)
    print enc

    print 'Corrupting message (random) ...'
    rec = []
    for c in enc:
        e = 0
        for i in range(8): 
            r = random.randint(0,999)
            if r < 5:
                e |= 1
            e <<= 1
        rec.append(c ^ e)
    
    total = 0
    for (i,j) in zip(rec, enc):
        if i!=j:
            total += 1
    print total, 'corrupted characters detected ...'
    print rec

    print 'Decoding ...'
    dec = ecc_decode(rec)
    print dec
    if dec[1] == msg:
        print 'Decoded succesfully!'
    else:
        print 'Errors detected'
        print dec
        print msg



    print 'Corrupting message (burst) ...'
    rec = array.array('B', [c^255 for c in enc[:24]]) + enc[24:]
    
    total = 0
    for (i,j) in zip(rec, enc):
        if i!=j:
            total += 1
    print total, 'corrupted characters detected ...'
    print rec

    print 'Decoding ...'
    dec = ecc_decode(rec)
    print dec
    if dec[1] == msg:
        print 'Decoded succesfully!'
    else:
        print 'Errors detected'
        print dec
        print msg
Esempio n. 6
0
def ecc_decode(received_code):

    """ decode 'received_code'.

        'received_code' is the set of MAX_LENGTH * 4 bytes making up
        the received packet.

        the optimal decoded message is the one maximizing the
        posterior probability given the received code using Bayes
        rule. An iterative algorithm may be appropriate here but to
        keep things simple we will follow a simpler scheme where we
        just use the reverse map to detect the most probable message
        word.

    """

    length = MAX_LENGTH * 4
    div = MAX_LENGTH / 8

    assert len(received_code) == length
    
    ## break duplicate data into 2 parts and each part into high bit
    ## and low pit parts

    code_1_high = []
    code_1_low = []
    code_2_high = []
    code_2_low = []
    while received_code:
        (head, received_code) = (received_code[:div], received_code[div:])
        code_1_high.extend(head)
        (head, received_code) = (received_code[:div], received_code[div:])
        code_2_high.extend(head)
        (head, received_code) = (received_code[:div], received_code[div:])
        code_1_low.extend(head)
        (head, received_code) = (received_code[:div], received_code[div:])
        code_2_low.extend(head)
    
    ## transpose
    tr_code_1_high = reverse_bit_transpose(code_1_high)
    tr_code_1_low = reverse_bit_transpose(code_1_low)
    tr_code_2_high = reverse_bit_transpose(code_2_high)
    tr_code_2_low = reverse_bit_transpose(code_2_low)

    
    # decode
    dec_code = []
    has_error = False
    for i in range(MAX_LENGTH):
        high1 = REVERSE_MAP[tr_code_1_high[i]] 
        low1 = REVERSE_MAP[tr_code_1_low[i]] 
        high2 = REVERSE_MAP[tr_code_2_high[i]] 
        low2 = REVERSE_MAP[tr_code_2_low[i]] 
        c = 0
        ## do high bits
        if high1 < 16 and high2 < 16:
            if high1 == high2:
                c = high1
            else:
                has_error = True

        elif high1 < 16 and high2 == 16:
            c = high1

        elif high1 == 16 and high2 < 16:
            c = high2
        
        else:
            has_error = True
        
        c <<= 4

        ## do low bits
        if low1 < 16 and low2 < 16:
            if low1 == low2:
                c |= low1
            else:
                has_error = True

        elif low1 < 16 and low2 == 16:
            c |= low1

        elif low1 == 16 and low2 < 16:
            c |= low2
        
        else:
            has_error = True
        
        dec_code.append(c)

    return (has_error, s_to_a(dec_code))