Java “任何压缩256字节的方法”;MD5 like“;字符串转换为160字节或更少?

Java “任何压缩256字节的方法”;MD5 like“;字符串转换为160字节或更少?,java,android,compression,Java,Android,Compression,我打算发送这样一个字符串(256字节): 通过安卓手机短信,内容应在1条短信内 您可能知道,SMS对每条消息的限制为160字节,我曾尝试在Java中使用gzip,然后用Base 64对压缩的内容进行编码,但压缩比不是很好 由于压缩数据将通过SMS发送,因此应该有一种编码方法使压缩字符串“可传输” 有什么想法吗 感谢您的评论/回答 如果转换为二进制,则从256个十六进制数字转换为128个字节。然后使用(或修改)中提到的其中一种技术将SMS转换为可接受的字符集。(该线程处理目标JSON,但同样的思想

我打算发送这样一个字符串(256字节):

通过安卓手机短信,内容应在1条短信内

您可能知道,SMS对每条消息的限制为160字节,我曾尝试在Java中使用gzip,然后用Base 64对压缩的内容进行编码,但压缩比不是很好

由于压缩数据将通过SMS发送,因此应该有一种编码方法使压缩字符串“可传输”

有什么想法吗


感谢您的评论/回答

如果转换为二进制,则从256个十六进制数字转换为128个字节。然后使用(或修改)中提到的其中一种技术将SMS转换为可接受的字符集。(该线程处理目标JSON,但同样的思想也可以应用于SMS。)

如果将其转换为二进制,则可以从256个十六进制数字转换为128个字节。然后使用(或修改)中提到的其中一种技术将SMS转换为可接受的字符集。(该线程处理JSON目标,但同样的思想也可以应用于SMS。)

你不能完全做到这一点。原因是,类似MD5的数据最大化了熵,因此gzip和朋友们很难接近50%的效率,即使他们做到了,也可能是命中或未命中

最佳的2:1压缩是:将每2个字符视为十六进制字节,并将其转换为二进制字符。这将把尺寸减小到1/2。但是,二进制数据无法发送,因此您必须对其进行base64编码,从而导致33%的增长。那就剩下170个字符了。“Base-128”编码不会有帮助,因为没有128个字符肯定会传输


简而言之,您需要减少数据量。毕竟,发送更少数据的最简单方法就是拥有更少的数据:)

你不可能做到这一点。原因是,类似MD5的数据最大化了熵,因此gzip和朋友们很难接近50%的效率,即使他们做到了,也可能是命中或未命中

最佳的2:1压缩是:将每2个字符视为十六进制字节,并将其转换为二进制字符。这样可以把尺寸降到1/2。但是,二进制数据无法发送,因此您必须对其进行base64编码,从而导致33%的增长。那就剩下170个字符了。“Base-128”编码不会有帮助,因为没有128个字符肯定会传输


简而言之,您需要减少数据量。毕竟,发送较少数据的最简单方法是拥有较少的数据:)

这实际上取决于您试图发送的确切数据类型


如果您的数据中存在可预测的模式,您可能可以使用预定义的符号字母表来降低您的大小。

这实际上取决于您尝试发送的确切数据类型


如果您的数据中存在可预测的模式,您可能可以使用预定义的符号字母表来减小大小。

该字符串是十六进制编码的。因此,它使用了二进制消息的200%空间

如果改用base64编码,它将使用134%,即171个字符。还是有点太多了


,这是我的一个亲戚发明的,可以做到。它将使用160个字符。

该字符串是十六进制编码的。因此,它使用了二进制消息的200%空间

如果改用base64编码,它将使用134%,即171个字符。还是有点太多了

,这是我的一个亲戚发明的,可以做到。它将使用160个字符。

您可以使用ascii85(PostScript使用的ascii85版本),因为 也压缩任何零字节序列。以下是Python shell中的转换:

>>> a = b'633a88d35a0f8fd172bd21158a03a8bb17ddc0acc6edb8ae19a9dbd1aa855b75319e540910fb70cf7bb51d608219dd4b387623f94262705a9c2c19332240e2a6d696d4cb896abf0101afae1aeebf3d6299675e0e67904e7a544de9e3e65fb9def9b0b047fb57a0b742226d602d386d9e2fe176a88837eddd0c77d6911d386c2e'

>>> ascii85_encoded = base85_encode(hex_decode(a))
>>> repr(ascii85_encoded) 
b'@lfFp=q?\\AEkNV2M?Bfh(Yum.`pL:=)6)B<WeFZ"0qM>N&GpFmHaOl%Jf3B;3-HPB6=On;S1GO6,!b.bes=h/M/\'d+!O&XEm_:noR:fh9B95l7<))W;k$P[Uq67(nqcBH"66^8S/N@U=0B%)QLc=_W%!U9b*B7jf' 

>>> len(ascii85_encoded)
160
>a=b'633A88D35A0F8FD172BD21158A03A8BB17DDC0acc6EDB8AE19A9DBD1AA855B75319E540910FB70CF7BB51D608219DDB387623F94262705A9C2C19332240E2A6D696D48986ABF0101AFAE1AEEBF3D6299675E0E6790E7A544DE9E65FB9DEF9B047FB57A074222D602D3869E2FE176A837EDDC77D6916C2E'
>>>ASCI85_编码=base85_编码(十六进制解码(a))
>>>报告(ASCI85_编码)
b'@lfFp=q?\\AEkNV2M?Bfh(Yum.`pL:=)6)b您可以使用ascii85(PostScript使用的ascii85版本),因为
也压缩任何零字节序列。以下是Python shell中的转换:

>>> a = b'633a88d35a0f8fd172bd21158a03a8bb17ddc0acc6edb8ae19a9dbd1aa855b75319e540910fb70cf7bb51d608219dd4b387623f94262705a9c2c19332240e2a6d696d4cb896abf0101afae1aeebf3d6299675e0e67904e7a544de9e3e65fb9def9b0b047fb57a0b742226d602d386d9e2fe176a88837eddd0c77d6911d386c2e'

>>> ascii85_encoded = base85_encode(hex_decode(a))
>>> repr(ascii85_encoded) 
b'@lfFp=q?\\AEkNV2M?Bfh(Yum.`pL:=)6)B<WeFZ"0qM>N&GpFmHaOl%Jf3B;3-HPB6=On;S1GO6,!b.bes=h/M/\'d+!O&XEm_:noR:fh9B95l7<))W;k$P[Uq67(nqcBH"66^8S/N@U=0B%)QLc=_W%!U9b*B7jf' 

>>> len(ascii85_encoded)
160
>a=b'633A88D35A0F8FD172BD21158A03A8BB17DDC0acc6EDB8AE19A9DBD1AA855B75319E540910FB70CF7BB51D608219DDB387623F94262705A9C2C19332240E2A6D696D48986ABF0101AFAE1AEEBF3D6299675E0E6790E7A544DE9E65FB9DEF9B047FB57A074222D602D3869E2FE176A837EDDC77D6916C2E'
>>>ASCI85_编码=base85_编码(十六进制解码(a))
>>>报告(ASCI85_编码)

b'@lfFp=q?\\AEkNV2M?Bfh(Yum.`pL:=)6)b为什么不仅使用前160个字节?256个字节或(您的示例看起来像)256个十六进制字符(128个字节)?@Peter R。正如thomasrutter所说,它用于会话密钥或其他类似用法。@ss1271是的,也许这样的用法没有多大用处sense@PeterR.所以如果字符串被截断,接收器将无法继续下一步的计算…:)为什么不只使用前160个字节?256个字节或(你的例子看起来像)256个十六进制字符(128个字节)?@Peter R。就像thomasrutter说的,它用于会话密钥或类似的用法。@ss1271是的,也许这样的用法没有多大用处sense@PeterR.所以如果字符串被截断,接收器将无法继续下一步的计算…:)使用base85而不是base64将节省约7%,这应该足以勉强应付。@Matt-理论上是正确的,但非二进制边界编码是一个真正的痛苦,然后你必须将整个混乱视为一个数字——eek!此外,由于我们最终必须以二进制形式将其表示为字符,这可能会导致效率低下。base85将每4个字节压缩为5个字符。因此,您实际上只是将每5个字符转换回一个32位值。它并没有那么复杂——当然没有gzip那么复杂。@thomas:好啊