我正在编写一个将字符串从一个字母转换为另一个字母的实用程序类,这在您希望使用目标字母表的情况下非常有用,并且对可用字符数有限制。例如,如果您可以使用小写字母和数字,但只能使用12个字符,则可以将字母01234567989 -:
中的时间戳压缩为abcdefghijklmnopqrstuvwxyz01234567989
,以便2010-10-29 13:14:00
可能变为5hhyo9v8mk6avy
(19个特征减少到16个)。
该类旨在在字母表之间来回转换,并计算可以安全地存储在给定特定字符数的目标字母表中的最长源字符串。
考虑通过Google代码发布此内容,但我显然希望其他人能够找到它并使用它 - 因此这就是所谓的问题。我不得不在两个独立的项目中使用这种方法,使用Bloomberg和专有系统,当你需要生成一定长度的唯一文件名,但想要保留一些明文时,所以GUID是不合适的。
答案 0 :(得分:2)
您的示例与具有固定目标和源词典的Dictionary coder有一些相似之处。另外值得一看的是Fibonacci coding,它有一个固定的目标字典(可变长度位),它是可变目标的。
我认为这也取决于您的目标字母表是否具有固定宽度条目非常重要 - 如果您允许使用可变长度代码的固定字母表,您的压缩比将更接近您的熵!如果事先知道源字母分布,则很容易生成静态Huffman tree。
答案 1 :(得分:1)
这是一个简单的算法:
考虑您不必传输用于编码的字母表。此外,您不使用(并传输)输入符号的概率,如在标准压缩中,因此我们只是以某种方式重新编码数据。
在这种情况下,我们可以认为输入数据的数字用base表示,等于输入字母表的基数。我们只需将其表示更改为另一个基础,这是一项简单的任务。
编辑示例:
输入alpabet:ABC
,输出字母:0123456789
消息ABAC
将转换为基数3中的0102
,即基数为10(9 + 2)。
11
以10为基础:11
我们可能在解码它时遇到问题,因为我们不知道在解码结果开始时要使用多少0-es,所以我们必须使用其中一个修改:
1)在流中以某种方式编码压缩数据的大小。
2)在流的开头使用虚拟1:这样我们的例子将成为:
10102
(基数3)= 81 + 9 + 2 = 92
(基数10)。
现在解码后我们只需要忽略第一个1
(这也提供了基本的错误检测)。
这种方法的主要问题是在大多数情况下(GCD == 1),每个新的编码字符将完全改变输出。这将非常有效且难以实施。我们最终将算术编码作为最佳解决方案(实际上是它的简化版本)。
答案 2 :(得分:0)
你可能知道Base64通常以相反的方式做同样的事情。太糟糕了,在BaseX或BaseN上有太多的谷歌搜索结果...