5

我有一个奇怪的通信通道,我需要检测错误并消除通道中的某些序列。

每条消息长 12 位,分成 3 个半字节(每个 4 位)。我需要从中提取至少 450 个不同的代码,这样我的汉明距离就可以达到 3。

但是,我不能让两个半字节序列相同,因此以下序列无效:

0xf 0xf 0xf - Three of the same nibbles in sequence
0x8 0x8 0x0 - Two of the same nibbles in sequence
0xf 0x3 0x3 - Two of the same nibbles in sequence

此外,消息可以不间断地相互跟随,因此一个序列的开头不能与最后一个序列的结尾具有相同的第一个半字节:

0x327 0x743 - Even though they are not in the same message, two sequential nibbles are the same in the message stream

但是以下序列很好:

0x1 0x2 0x1 - Two nibbles same, but separated by another nibble
0x0 0x1 0x2 - All nibbles different
0xf 0x8 0x3 - All nibbles different

以下一系列消息很好:

0x121 0x012 0xf83 - No two adjacent nibbles are the same is the stream of messages

我的第一个想法是为我的消息使用 9 位,分成三个 3 位部分作为每个半字节的最高位:

mmmc mmmc mmmc - Each character is a bit, m bits are message, c bits are checksum/parity/etc

然后设计一个 512 条目表,给我三个要填充的位c,这将创建汉明距离,同时消除麻烦的序列。

但是,这将在低端嵌入式处理器上运行,如果我可以使用算术动态生成c位,它将节省内存(以换取更多的处理器时间),这在这种情况下更有价值。

有没有我可以执行的一些数学运算可以在没有表格的情况下解决这个问题?

或者,是否有另一种符合要求的数学打包方法?

4

1 回答 1

5

最简单的方法:
0mmm 1mmm 0mmm - 没有重复的半字节,最快的编码/解码,没有校验和

但我推荐以下方法:
您有 3600 = 16*15*15 个可能的半字节三元组(第一个半字节有 16 个变体,第二个有 15 个,第三个有 15 个)。
您可以有 2 位校验和和 3600/4 = 900 个域特定代码。

编码器(解码器是它的反面):

C = 0..899 -- your code to be encoded  
C = C * 4  -- appending a "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  

如果没有 DIV 操作, 除以 15 就像乘以 0.000100010001 2一样简单。

解码器:

nibble1, nibble2, nibble3 -- your three 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 then CHECKSUM ERROR
C = C/4  -- 0..899

新条件的UPD
: 无校验和,8*14*8 = 896 个可能的代码

编码器(解码器是它的反面):

C = 0..895 -- your code to be encoded  
N1 = C mod 8
C = C div 8
N2 = (C div 8) + 1 + N1
N3 = (C mod 8) + 8
if N2 >= N3 then N2 = N2 + 1
nibble1 = N1   -- 0..7
nibble2 = N2 mod 16
nibble3 = N3   -- 8..15

解码器:

nibble1, nibble2, nibble3 -- your three nibbles (0..7, 0..15, 8..15)
N1 = nibble1
N2 = (nibble2 - nibble1 - 1) mod 16
N3 = nibble3
if N1 + N2 >= N3 then N2 = N2 - 1
C = (N2*8 + N3 - 8)*8 + N1  -- 0..895
于 2013-05-15T01:52:51.003 回答