随机字符串应该是不可压缩的。
pi = "31415..."
pi.size # => 10000
XZ.compress(pi).size # => 4540
随机十六进制字符串也会得到显着压缩。但是,随机字节字符串不会被压缩。
pi的字符串仅包含字节48到57.如果整数上有前缀代码,则可以对此字符串进行大量压缩。基本上,我通过以字节为单位表示我的9个不同字符来浪费空间(或者在十六进制字符串的情况下为16)。这是怎么回事?
有人可以向我解释底层方法是什么,或者指向某些来源吗?
答案 0 :(得分:4)
这是信息密度的问题。压缩就是要删除冗余信息。
在字符串"314159"
中,每个字符占用8位,因此可以具有2个 8 或256个不同值中的任何一个,但实际上只使用了其中的10个值。即使是一个痛苦的天真压缩方案也可以使用每位4位来表示相同的信息;这被称为二进制编码十进制。更复杂的压缩方案可以做得更好(十进制数字实际上是log 2 10,或大约3.32,位),但代价是存储一些允许解压缩的额外信息。
在随机十六进制字符串中,每个8位字符有4个有意义的位,因此应该可以压缩近50%。字符串越长,越接近50%。如果您事先知道字符串只包含十六进制数字,则可以将其压缩50%,但当然会失去压缩其他任何内容的能力。
在随机字节字符串中,没有压缩机会;你需要每个字符的整个8位来表示每个值。如果它是真正随机的,尝试压缩它可能会稍微扩展它,因为需要一些额外的信息来指示输出是压缩数据。
解释压缩如何工作的细节超出了本答案的范围和我的专业知识。
答案 1 :(得分:-1)
除了Keith Thompson's excellent answer之外,还有另一个与LZMA相关的点(这是XZ格式使用的压缩算法)。数字pi不是由一个重复的数字串组成,但它们也不是完全随机的。它确实包含substrings of digits,它们在较大的序列中重复。 LZMA可以检测这些并仅存储重复子串的单个副本,从而减小压缩数据的大小。