4

我的问题是如何将 cmd ARGV 的 STDIN 或从十六进制转换为 ascii

我知道如果我将十六进制字符串分配给变量,一旦我打印它就会被转换

前任

hex_var = "\x41\41\x41\41"
puts hex_var

结果将是

AAAA

但我需要通过(ARGV 或获取)从命令行获取值

说我有这行

s = ARGV

puts s
# another idea
puts s[0].gsub('x' , '\x')

然后我跑了

ruby  gett.rb \x41\x41\x41\x41 

我有

\x41\x41\x41\x41

有没有办法让它工作?

4

2 回答 2

1

在控制台中输入的反斜杠将由 shell 解释并且不会进入您的 Ruby 脚本,除非您连续输入两个反斜杠,在这种情况下,您的脚本将获得文字反冲并且不会自动转换后面的十六进制字符代码强烈反对。

如果将脚本的最后一行替换为以下代码,则可以手动将这些转义代码转换为字符:

puts s.gsub(/\\x([[:xdigit:]]{1,2})/) { $1.hex.chr }

然后使用双重反冲输入运行它:

$ ruby gett.rb \\x41\\x42\\x43
ABC

当通过gets或类似方法获取用户输入时,用户只需要为每个字符转义输入一个反斜杠,因为它确实会作为文字反斜杠传递给您的脚本,因此上述gsub调用可以正确处理。


解析命令行参数的另一种方法是让 shell 为您解释字符转义。如何做到这一点取决于您使用的外壳。如果使用bash,可以这样做:

$ echo $'\x41\x42\x43'
ABC
$ ruby -e 'puts ARGV' $'\x41\x42\x43'
ABC
于 2012-05-05T21:15:05.723 回答
1

您在这里要处理几个问题。您已经尝试解决第一个问题,但我认为您的解决方案并不理想。您使用命令行参数传入的反斜杠正在由 shell 评估,并且永远不会进入 ruby​​ 脚本。如果您只想在脚本中执行 gsub,则甚至没有理由将它们传入。按照您的方式进行操作意味着参数中的任何“x”都将被换掉,即使是那些不习惯的表示一个十六进制。如果可能的话,最好对参数中的 \ 进行双重转义。如果没有价值来自哪里的背景,很难说方式实际上会更好。

ruby gett.rb \\x41\\x41

这样 ARGV 实际上会得到 '\x41\x41',这更接近你想要的。

但是,它仍然不是您想要的,因为 ARGV 参数是在没有表达式替换的情况下创建的(就像它们在单引号中一样)。所以 Ruby 正在逃避那个 \ 即使你不想要它。本质上,您需要接受它并重新评估它,就好像它在双引号中一样。

eval('"%s"' % s)

其中 s 是字符串。

因此,将它们放在一起,您最终可能会得到以下任何一种:

# ruby gett.rb \x41\x41

ARGV.each do |s|
  s = s.gsub('x' , '\x')
  p eval('"%s"' % s)
end
# => "AA"

# ruby gett.rb \\x41\\x41

ARGV.each do |s|
  p eval('"%s"' % s)
end
# => "AA"
于 2012-05-05T17:20:03.653 回答