gpt4 book ai didi

ruby - ruby中打包ASCII算法更优雅的实现

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:06:11 25 4
gpt4 key购买 nike

我需要解压缩压缩的 ASCII 字符字符串。算法如下:

  1. 得到 3 个打包的 ASCII 字节,将它们放入 4 个 ASCII 字节。 (6 + 6 + 6 + 6 bits in 3 bytes to 4 bytes)
  2. 对于每个字节,将位 6 设置为位 5 的补码。
  3. 对于每个字节,将第 7 位重置为零。
  4. 重复接下来的 3 个打包字节。

我是 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:​​感谢对收集的更正。

最佳答案

尽管 ruby 的 Array#packString#unpack不直接支持 ASCII 打包和解包,它们通过 pack('m') 支持 Base64和 unpack('m') .这有助于位移位转换,即与每个包含 8 个相关位的 3 个字节和每个包含 6 个相关位的 4 个字节相互转换。

这是 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-pack 的人来说,这是一种“有损”压缩。 ASCII 字符 x超出范围 0x20 <= x < 0x60被翻译成该范围内的字符。这就是为什么小写字母在打包/解包时会变成大写的原因。

关于ruby - ruby中打包ASCII算法更优雅的实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23408682/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com