algorithm - Eliminating sequences in a message -
i have odd communications channel, , need detect errors eliminate sequences in channel.
each message 12 bits long, split 3 nibbles (of 4 bits each). need extract @ least 450 different codes out of this, can have hamming distance of 3.
however, cannot have 2 nibbles in sequence same, following sequences invalid:
0xf 0xf 0xf - 3 of same nibbles in sequence 0x8 0x8 0x0 - 2 of same nibbles in sequence 0xf 0x3 0x3 - 2 of same nibbles in sequence
further, messages can follow each other without breaks, beginning of 1 sequence can't have same first nibble end of last sequence:
0x327 0x743 - though not in same message, 2 sequential nibbles same in message stream
but following sequences fine:
0x1 0x2 0x1 - 2 nibbles same, separated nibble 0x0 0x1 0x2 - nibbles different 0xf 0x8 0x3 - nibbles different
and following series of messages fine:
0x121 0x012 0xf83 - no 2 adjacent nibbles same stream of messages
my first thought use 9 bits message, split 3 three bit parts top bits of each nibble:
mmmc mmmc mmmc - each character bit, m bits message, c bits checksum/parity/etc
then design 512 entry table gives me 3 bits fill c
create hamming distance while eliminating troublesome sequences.
however, running on low end embedded processor, , if can use arithmetic generate c
bits on fly, save memory (in exchange more processor time) more valuable in case.
is there bit of math can perform solve problem without table?
alternately, there packing method math meet requirements?
the simplest method:
0mmm 1mmm 0mmm - no repeating nibbles, fastest encoding/decoding, no checksum
but i'd recommend following method:
have 3600 = 16*15*15 possible nibble triplets (first nibble has 16 variants, second has 15, third has 15).
can have 2 bits checksum , 3600/4 = 900 domain-specific codes.
encoder (decoder reverse of it):
c = 0..899 -- code encoded c = c * 4 -- appending "hidden checksum" n3 = c mod 15 -- 0..14 c = c div 15 n2 = c mod 15 -- 0..14 n1 = c div 15 -- 0..15 nibble1 = n1 nibble2 = (nibble1 + 1 + n2) mod 16 nibble3 = (nibble2 + 1 + n3) mod 16
dividing 15 simple multiplying 0.0001000100012 if haven't div operation.
decoder:
nibble1, nibble2, nibble3 -- 3 nibbles n1 = nibble1 n2 = (nibble2 - nibble1 - 1) mod 16 n3 = (nibble3 - nibble2 - 1) mod 16 c = (n1*15 + n2)*15 + n3 if c mod 4 != 0 checksum error c = c/4 -- 0..899
upd new conditions:
no checksum, 8*14*8 = 896 possible codes
encoder (decoder reverse of it):
c = 0..895 -- code encoded n1 = c mod 8 c = c div 8 n2 = (c div 8) + 1 + n1 n3 = (c mod 8) + 8 if n2 >= n3 n2 = n2 + 1 nibble1 = n1 -- 0..7 nibble2 = n2 mod 16 nibble3 = n3 -- 8..15
decoder:
nibble1, nibble2, nibble3 -- 3 nibbles (0..7, 0..15, 8..15) n1 = nibble1 n2 = (nibble2 - nibble1 - 1) mod 16 n3 = nibble3 if n1 + n2 >= n3 n2 = n2 - 1 c = (n2*8 + n3 - 8)*8 + n1 -- 0..895
Comments
Post a Comment