ruby中压缩ASCII算法的更优雅实现
我需要解压压缩的ASCII字符字符串。算法如下:ruby中压缩ASCII算法的更优雅实现,ruby,algorithm,Ruby,Algorithm,我需要解压压缩的ASCII字符字符串。算法如下: 获取3个压缩ASCII字节,将它们放入4个ASCII字节。(3字节到4字节中的6+6+6位) 对于每个字节,将第6位设置为第5位的补码 对于每个字节,将位7重置为零 对接下来的3个压缩字节重复此操作 我是Ruby新手,也许有更正确、更优雅的方法来解决这个问题,而不是我的代码: while i < pstr.length parr = [pstr[0] & 0x3F, pstr[0]>>6 | ((pstr[1]
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
而i>6 |((pstr[1]>4 |)((pstr[2]>2]
parr.collect!{| a | a |(~(a虽然ruby's不直接支持ASCII打包和解包,但它们通过pack('m')
和unpack('m')
)支持Base64。这有助于转换3个字节(每个字节包含8个相关位)和4个字节(每个字节包含6个相关位)所涉及的位移位
这里是pack
和unpack
的一个开始实现,它更像是ruby风格。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包的人来说,它是一种“有损”压缩。ASCII字符x
超出范围0x20只是为了澄清:您的代码按预期工作(例如通过测试),但您想获得Ruby习惯用法或捷径方面的帮助吗?您能为问题添加一些测试输入和验证输出吗,这会有所帮助。您看过#unpack
?@Urigassi正如我在文档中读到的,Ruby不支持pack/unpack中的压缩ASCII代码。@NeilSlater代码适用于我拥有的示例,但ofc有bug,只是想澄清一下如果我正确理解Ruby的结构,使用Ruby功能无法以更简洁的方式解决这个问题。感谢对collect的更正。您能提供两个测试样本吗?