ruby base64编码/解码/解包(‘m’)麻烦
遇到奇怪的
ruby编码:
ruby-1.9.2-p180 :618 > s = "a8dnsjg8aiw8jq".ljust(16,'=') => "a8dnsjg8aiw8jq==" ruby-1.9.2-p180 :619 > s.size => 16 ruby-1.9.2-p180 :620 > s.unpack('m0') ArgumentError: invalid base64 from (irb):631:in `unpack' ruby-1.9.2-p180 :621 > s.unpack('m') => ["kxC7gxB28<j,<x8E"] ruby-1.9.2-p180 :622 > s.unpack('m').first.size => 10 ruby-1.9.2-p180 :623 > s.unpack('m').pack('m') => "a8dnsjg8aiw8jg==n" ruby-1.9.2-p180 :624 > s.unpack('m').pack('m') == s => false 知道为什么这不对称!?为什么’m0′(decode64_strict)根本不工作?输入字符串填充为base64字母表中的4个字符的倍数.这里是14×6比特= 84比特,即10 1/2 8比特字节,即11字节.但是解码后的字符串似乎会丢掉最后一个nybble? 我错过了一些明显的东西或者这是一个错误吗?解决方法? 解决方法
没有对称性,因为Base64不是填充字符串的一对一映射.让我们从实际解码的内容开始.如果你用十六进制查看你的解码字符串(使用例如s.unpack(‘H *’),它将是这样的:
6B C7 67 | B2 38 3C | 6A 2C 3C | 8E 我将每个输入块的边界添加到Base64算法:它需要3个八位字节的输入并返回4个字符的输出.所以我们的最后一个块只包含一个输入八位字节,因此结果将是4个字符,根据标准以“==”结尾. 让我们看看最后一个块的规范编码是什么.在二进制表示中,8E是10001110.RFC告诉我们用零填充缺失的位,直到达到所需的24位: 100011 100000 000000 000000 我创建了6位组,因为这是我们从Base64字母表中获取相应字符所需要的.第一组(100011)转换为35十进制,因此是Base64字母表中的j.第二个(100000)是十进制32,因此是’g’.根据规则,剩下的两个字符将被填充为“==”.所以规范编码是 jg== 如果你看看jq == now,那么二进制就是这样 100011 101010 000000 000000 所以区别在于第二组.但是因为我们已经知道只有前8位是我们感兴趣的(“==”告诉我们 – >>我们只会从这四个字符中检索一个解码的八位字节)我们实际上只关心前两位第二组,因为组1的6位和组2的2位形成我们的解码八位组. 100011 10一起形成我们的初始8E字节值.剩余的16位与我们无关,因此可以被丢弃. 这也意味着为什么“严格”Base64编码的概念有意义:非严格解码将在最后丢弃任何垃圾,而严格解码将检查最后6个组中的剩余比特为零.这就是严格的解码规则将拒绝您的非规范编码的原因. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |