为什么Ruby将整数转换为八进制转义字符串而不是十六进制转义字符串?

时间:2015-02-25 14:34:42

标签: ruby string type-conversion hbase jruby

我需要:

"ff".hex.chr #=> "\xff"

但我得到了:

"ff".hex.chr #=> "\377"

我的错误在哪里?缺什么?环境是HBase 0.98.6 shell,它似乎基于JRuby 1.6.8控制台。

2 个答案:

答案 0 :(得分:2)

"\xff""\377"是同一数据的不同表示形式:

  • "\xff"是十六进制的,是典型的较新Ruby版本。
  • "\377"是八进制的,是典型的旧版Ruby。

您可以看到相同的数字如何产生不同的字符串:

printf("%o",255) #=> "377"
printf("%x",255) #=> "ff"

默认表示通常是由于您的控制台设置和Ruby版本。

通常,即使在相同的Ruby版本上,也不要依赖String#inspect来产生一致的表示。如果您使用某些特殊字符,则可以看到此操作:

"\007" #=> "\a"

String#inspect方法已将表示更改为八进制或十六进制。

如果您要输出到需要特定格式的系统,您可以明确:

printf("\\x%x", 255) #=> \xff  # lower case
printf("\\x%X", 255) #=> \xFF  # upper case

您还可以尝试packunpack方法:

["ff"].pack("H*") #=> "\xFF"

如果您的字符串始终是十六进制数字,并且您所需的输出只是插入" \ x"在每两个字符前面,然后有一个快速的解决方案:

print "a1b2c3".gsub(/../){"\\x#{$&}"}
#=> \xa1\xb2\xc3

快速介绍Ruby字符串表示以及如何使用不可打印的字符在Safari Books Ruby Cookbook

答案 1 :(得分:0)

经验教训:

  • 实际上八位字节没有任何功能问题。只是代表(感谢所有评论和答案)。内部字符串内容相同。
  • 是的,在Ruby 1.8中,String#inspect with"%03o"格式。是的,HBase 0.98.6将这个Ruby版本用于JRuby 1.6.8。在我的情况下,这不容易解决。
  • 检查与实际结果无关,因此我使用了Hbase Bytes类,并为需要查看预期密钥表示的人准备了特殊printer

这是实际解决我所有任务的代码,包括想要的输出:

# Convert binary string to hex digits.
def bin_to_hex(s)
  s.each_byte.map { |b| b.to_s(16).rjust(2, '0') }.join
end

# Convers hex string to binary string.
def hex_to_bin(s)
  s.scan(/../).map { |x| x.hex.chr }.join
end

# HBase special 'convert and print' routine to get hex digits, process them and print.
def print_hex_to_bin(s)
  Kernel.print "\"" + Bytes.toStringBinary(s.scan(/../).map { |x| x.hex.chr }.join.to_java_bytes) + "\"\n"
end

主要根据http://anthonylewis.com/2011/02/09/to-hex-and-back-with-ruby/

组成
相关问题