Ruby - 将"=="十六进制值与字符串进行比较

4 ruby string encoding hex

我基本上是在图片文件的标题中阅读并进行快速比较,以查看它实际上是什么类型的文件.BMP,GIF,PNG都很简单,因为它们的标题分别包含BM,GIF和PNG以识别自己.JPG给我带来了一些循环.

jpg的前3个字节往往是0xff\0xd8\0xff,在我的生命中,无论我如何设置它,我都无法通过简单的比较得到真正的值.

我读了前4个字节:

if data[0, 3] == "\xff\xd8\xff"
    puts "This is a JPG"
end
Run Code Online (Sandbox Code Playgroud)

我知道我很接近,但我无法让它发挥作用.请让我知道我在这里错过了什么.

注意:我知道有宝石为我做这个,但我不想使用宝石.就那么简单.

Ste*_*fan 9

这是一个字符编码问题.从JPEG读取前4个字节将返回ASCII编码的字符串:

head = File.read("some.jpg", 4)
# => "\xFF\xD8\xFF\xE1"

head.encodig
# => #<Encoding:ASCII-8BIT>
Run Code Online (Sandbox Code Playgroud)

另一方面,字符串是UTF-8编码的:

jpg_prefix = "\xff\xd8\xff"
# => "\xFF\xD8\xFF"

jpg_prefix.encoding
# => #<Encoding:UTF-8>
Run Code Online (Sandbox Code Playgroud)

比较UTF-8和ASCII字符串不能按预期工作:

head[0,3] == jpg_prefix
# => false
Run Code Online (Sandbox Code Playgroud)

您必须使用以下命令显式设置编码String#force_encoding:

jpg_prefix = "\xff\xd8\xff".force_encoding(Encoding::ASCII_8BIT)
# => "\xFF\xD8\xFF"

jpg_prefix.encoding
# => #<Encoding:ASCII-8BIT>

head[0,3] == jpg_prefix
# => true
Run Code Online (Sandbox Code Playgroud)

使用Integer#chr(由Mario Visic建议)创建的串联ASCII字符也有效:

jpg_prefix = 0xff.chr + 0xd8.chr + 0xff.chr
# => "\xFF\xD8\xFF"

jpg_prefix.encoding
# => #<Encoding:ASCII-8BIT>
Run Code Online (Sandbox Code Playgroud)

或者使用Array#pack:

jpg_prefix = ["FFD8FF"].pack("H*")
# => "\xFF\xD8\xFF"

jpg_prefix.encoding
# => #<Encoding:ASCII-8BIT>
Run Code Online (Sandbox Code Playgroud)