从1D条形码读取的关键值对的高效压缩和表示

时间:2013-03-07 11:00:46

标签: compression barcode huffman-code code128

我目前正在为Windows Mobile编写一个应用程序,它需要能够从一维条形码(配置设置)中获取键值对。需要扫描的条形码越少越好。样本输入:

------------------------------
| Key | Value                |    
------------------------------
| 12  | Söme UTF-8 Strîng    |
|  9  | & another string     |
------------------------------

我想到了以下算法:

1。 Concat键值对并使用Base64

对值进行编码

所以我们会得到像12=U8O2bWUgVVRGLTggU3Ryw65uZw==&9=JiBhbm90aGVyIHN0cmluZw==

这样的东西

2。使用霍夫曼编码压缩数据

我会使用固定的霍夫曼树,以下信息可以帮助我压缩数据:

-------------------------------------------
| Enties                       | Priority |    
-------------------------------------------
| =, &                         | High     |
| 0-9                          | Medium   |
| 5-bit Base64 Words (w/o 0-9) | Low      |
-------------------------------------------

第3。从编码数据生成代码128B条形码

将Base96编码应用于由Huffman算法生成的位流,以获取可在Code 128B条形码中使用的ASCII字符。根据需要将生成的字符串拆分为多个条形码。

编写这些步骤对我来说不是问题,但我希望得到一些关于效率和算法设计的反馈。

问题

  • 我在某处失去了更好的压缩/短弦的潜力吗?
  • 是否有更好的方法来压缩随机UTF8编码数据?
  • 我应该将动态Huffman表嵌入到编码数据中吗?
  • 如何考虑代码128B的压缩(0需要的空间少于&)?

3 个答案:

答案 0 :(得分:1)

一种简单的方法是定义直接映射到code128的所有64个字符。这将留下30-40个可用代码128个插槽。在剩余的插槽中定义一些双字符。 == =& 0 = 1 = 2 = 3 = 4 = 5 = 6 = 7 = 8 = 9 =& 0& 1& 2& 5& 5& 5& 5& 8& 8& 9 (重复最后一个字符)= =(双下一个字符)&(双下一个字符)

答案 1 :(得分:0)

经过大量的游戏和摆弄,我们最终选择了这种方法:

<强> 1。将设置编码为字节流

字段值被序列化为字节流,每个字段都有一个标题。标头消耗一个字节并包含字段的ID和一些有助于减少要传输的数据量的标志。根据字段的类型(例如字符串,数字或IP地址),该值被有效地编码到字节流中。例如,IP地址用4个字节编码,而布尔标志直接编码到字段标题中。这样,如果需要,我们甚至可以将SSL证书编码到流中。由于典型的条形码格式无法传输任意字节值,我们需要在下一步中对字节流进行编码。

<强> 2。转换为条形码格式

现在,生成的字节数组被视为一个大的整数,并使用基本编码和字符集转换为目标条形码格式(请参阅this question)。这样,我们有效地使用条形码格式来传输我们的数据(与Base64或其他编码相反)。从结果字符串中,我们可以添加一些单个条形码并向它们添加一些额外的标题信息(例如,必须扫描多少个条形码?是加密的数据?...)。

当条形码在移动设备上扫描时,编码的字符串可以恢复并转换为相同的大整数。然后可以将此整数视为字节数组,可以在已知字段序列化格式时对其进行解析。

这种方法非常有效和快速(我们对CF上的BigInteger implementation有一些顾虑。)

答案 2 :(得分:0)

虽然某些条形码格式具有固定的字符集,但它们可以表示并使用相同的空间来容纳每个字符,而其他条形码格式使用多个字符集,或使用可变数量的空间来容纳每个字符。例如,“经典”代码39定义了43个字符,每个字符由43个符号中的一个表示,并且根本不能表示任何其他字符,但是还有另一个代码-39变体,它使用一个符号表示39个常见字符,而其他字符使用双字符序列。例如,假设有人希望在代码-39条形码中存储一堆二进制数据。如果将数据转换为base-64格式,则与三个八位字节的原始数据相关联的四个字符可能需要平均约5.69个符号来存储[base64中使用的64个字符中的大约27个需要两个符号来存储在代码39]。如果一个人选择了32个字符,每个字符可以用一个符号表示,则可以使用5个八位字节存储24个(或25个)比特,每个存储5个比特[每个八位字节一致1.67个符号,而平均值为1.89,最差情况为2.67 ]。如果使用“经典”代码39(每个代码使用一个符号可以代表43个字符),则甚至可以在六个符号中存储四个八位字节[平均每个八位字节1.5个符号]。

针对不同的字符集“优化”不同的条形码格式;像Code 128这样的一些字符集具有多个字符集,并且可以有效地用于使用一个字符集的全部范围的数据,同时避免使用其外部的字符。我不知道任何特别推荐的重新格式化数据的方法,以便优化特定符号系统字符集的使用,但检查符号系统使用的编码和您的特定要求应该可以帮助您确定哪种编码最适合您的应用