首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >解码base45字符串

解码base45字符串
EN

Stack Overflow用户
提问于 2021-06-24 19:14:59
回答 3查看 11.1K关注 0票数 8

我们正在尝试实现新的欧盟冠状病毒测试/疫苗接种证书的验证,但无法使base45解码工作。

规范在这里:https://datatracker.ietf.org/doc/draft-faltstrom-base45/

我们几乎完成了我们的课程,但有时我们会得到错误的值。

目标是:

代码语言:javascript
运行
复制
Encoding example 1: The string "AB" is the byte sequence [65 66].
The 16 bit value is 65 * 256 + 66 = 16706. 16706 equals 11 + 45 * 11
+ 45 * 45 * 8 so the sequence in base 45 is [11 11 8].  By looking up
these values in the Table 1 we get the encoded string "BB8".

Encoding example 2: The string "Hello!!" as ASCII is the byte
sequence [72 101 108 108 111 33 33].  If we look at each 16 bit
value, it is [18533 27756 28449 33].  Note the 33 for the last byte.
When looking at the values modulo 45, we get [[38 6 9] [36 31 13] [9
2 14] [33 0]] where the last byte is represented by two.  By looking
up these values in the Table 1 we get the encoded string "%69
VD92EX0".

Encoding example 3: The string "base-45" as ASCII is the byte
sequence [98 97 115 101 45 52 53].  If we look at each 16 bit value,
it is [25185 29541 11572 53].  Note the 53 for the last byte.  When
looking at the values modulo 45, we get [[30 19 12] [21 26 14] [7 32
5] [8 1]] where the last byte is represented by two.  By looking up
these values in the Table 1 we get the encoded string "UJCLQE7W581".

下面是我的当前代码,它产生了错误的值:

代码语言:javascript
运行
复制
class Base45

  ALPHABET = {
    "00" => "0",
    "01" => "1",
    "02" => "2",
    "03" => "3",
    "04" => "4",
    "05" => "5",
    "06" => "6",
    "07" => "7",
    "08" => "8",
    "09" => "9",
    "10" => "A",
    "11" => "B",
    "12" => "C",
    "13" => "D",
    "14" => "E",
    "15" => "F",
    "16" => "G",
    "17" => "H",
    "18" => "I",
    "19" => "J",
    "20" => "K",
    "21" => "L",
    "22" => "M",
    "23" => "N",
    "24" => "O",
    "25" => "P",
    "26" => "Q",
    "27" => "R",
    "28" => "S",
    "29" => "T",
    "30" => "U",
    "31" => "V",
    "32" => "W",
    "33" => "X",
    "34" => "Y",
    "35" => "Z",
    "36" => " ",
    "37" => "$",
    "38" => "%",
    "39" => "*",
    "40" => "+",
    "41" => "-",
    "42" => ".",
    "43" => "/",
    "44" => ":"
  }.freeze

  def self.encode_base45(text)
    restsumme = text.unpack('S>*')

    # not sure what this is doing, but without it, it works worse :D
    restsumme << text.bytes[-1] if text.bytes.size > 2 && text.bytes[-1] < 256

    bytearr = restsumme.map do |bytes|
      arr = []
      multiplier, rest = bytes.divmod(45**2)
      arr << multiplier if multiplier > 0

      multiplier, rest = rest.divmod(45)
      arr << multiplier if multiplier > 0
      arr << rest if rest > 0
      arr.reverse
    end
    return bytearr.flatten.map{|a| ALPHABET[a.to_s.rjust(2, "0")]}.join
  end

  def self.decode_base45(text)
    arr = text.split("").map do |char|
      ALPHABET.invert[char]
    end
    textarr = arr.each_slice(3).to_a.map do |group|
      subarr = group.map.with_index do |val, index|
        val.to_i * (45**index)
      end
      ap subarr
      subarr.sum
    end

    return textarr.pack("S>*") # returns wrong values
  end
end

结果:

代码语言:javascript
运行
复制
Base45.encode_base45("AB")
=> "BB8" # works
Base45.decode_base45("BB8")
=> "AB" # works

Base45.encode_base45("Hello!!")
=> "%69 VD92EX" # works
Base45.decode_base45("BB8")
=> "Hello!\x00!" # wrong \x00


Base45.encode_base45("base-45")
=> "UJCLQE7W581" # works
Base45.decode_base45("UJCLQE7W581")
=> "base-4\x005" # wrong \x00

任何建议都值得感谢:(

EN

Stack Overflow用户

发布于 2021-06-24 19:59:52

如果你想要一种简单的方式:

代码语言:javascript
运行
复制
return textarr.map{|x| x<256 ? [x].pack("C*") : [x].pack("n*") }.join

看看这个方案,这感觉像是一种奇怪的编码方式,因为我们正在处理数字...如果是我,我会从字符串的尾部开始,直到字符串的头部,但那是因为我们使用的是数字。

无论如何,我的bodge之所以有效,是因为它将小元素/数字视为8位无符号,而不是16位无符号。

..。

稍微美观一点,但可能也好不到哪里去:

代码语言:javascript
运行
复制
def self.decode_base45(text)
  arr = text.split("").map do |char|
    ALPHABET.invert[char]
  end
  textarr = arr.each_slice(3).to_a.map do |group|
    subarr = group.map.with_index do |val, index|
      val.to_i * (45**index)
    end
    ap subarr
    subarr.sum.divmod(256)
  end.flatten.reject(&:zero?)

  return textarr.pack("C*") # returns wrong values
end
票数 0
EN
查看全部 3 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68114693

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档