我需要解压缩打包的ASCII字符的字符串。该算法如下:
我是Ruby的新手,也许有解决该任务的更正确,更优雅的方法,而不是我的代码:
while i < pstr.length
parr = [pstr[0] & 0x3F, pstr[0]>>6 | ((pstr[1] << 2 ) & 0x3F),
pstr[1]>>4 | ((pstr[2] << 4 ) & 0x3F),
pstr[2]>>2]
parr.collect! { |a| a | (~(a << 1) & 0x20) }
parr.collect! { |a| a & 0x7F }
puts parr
i += 3
end
Update1:Thx用于更正收集。
尽管ruby的Array#pack和String#unpack不直接支持ASCII打包和解压缩,但它们确实通过pack('m')
和支持Base64 unpack('m')
。这可以帮助进行与从3个字节(每个保留8个相关位)和4个字节(每个保留6个)之间来回转换的位移位。
下面是一个开始实施pack
和unpack
这是一个有点更红宝石去年秋季。pack
对4的精确倍数的字符串进行运算,除去任何余数。相反,unpack
每3个字符将其扩展为4。
B64 = ('A'..'Z').to_a+('a'..'z').to_a+('0'..'9').to_a+%w(+ /) # Base64 alphabet
H64 = Hash[B64.zip(0..63)] # Hash character to index
# Translates every 4 characters to 3, drops any remainder
def pack( ascii )
ascii.bytes.map { |b| B64[b&(b&0x40==0?0x3f:0x1f)] }.join.unpack('m')[0]
end
# Translates every 3 characters to 4
def unpack( bstr )
[bstr].pack('m').chomp.split('').map do |c|
( (H64[c]|0x40) & (H64[c]&0x20==0?0x5f:0x3f) ).chr
end.join
end
用法示例:
ascii_packed = pack('Hello World!')
puts ascii_packed.length # => 9
puts unpack( ascii_packed ) # => "HELLO WORLD!"
对于不熟悉ASCII压缩的用户,这是一种“有损”压缩。x
超出范围的ASCII字符0x20 <= x < 0x60
将转换为该范围内的字符。这就是为什么小写字母在打包/拆包时大写的原因。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句