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

643ylb08  于 2021-06-09  发布在  Hbase
关注(0)|答案(2)|浏览(649)

我需要:

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

但我得到的却是:

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

我的错在哪里?少了什么?环境是hbase 0.98.6 shell,它似乎基于jruby1.6.8控制台。

kcrjzv8t

kcrjzv8t1#

"\xff" 以及 "\377" 相同数据的不同表示形式: "\xff" 是十六进制,是较新的ruby版本的典型。 "\377" 是八进制的,是旧版ruby的典型。
您可以看到相同的数字如何生成不同的字符串:

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

默认表示形式是一种典型的表示形式,这是由控制台设置和ruby版本决定的。
一般来说,不要依赖 String#inspect 即使在同一个ruby版本上,也要产生一致的表示。如果您使用一些特殊字符,您可以看到这一点:

"\007" #=> "\a"

这个 String#inspect 方法已将表示形式更改为既不是八进制也不是十六进制。
如果要输出到需要特定格式的系统,可以显式执行以下操作:

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

你也可以试试 pack 以及 unpack 方法:

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

如果您的字符串总是十六进制数字,并且您想要的输出只是在每两个字符前面插入“\x”,那么有一个快速的解决方案:

print "a1b2c3".gsub(/../){"\\x#{$&}"}

# => \xa1\xb2\xc3

关于ruby字符串表示和如何处理不可打印字符的快速介绍,请参阅safari books ruby cookbook

g9icjywg

g9icjywg2#

经验教训:
实际上,八位字节没有任何功能问题。只是陈述(感谢所有的评论和回答)。内部字符串内容相同。
是的,在Ruby1.8中有一个字符串#inspect,格式为“%03o”。是的,hbase0.98.6将这个ruby版本用于jruby1.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/

相关问题