如何在Ruby中将二进制字段转换为文本?

时间:2017-10-24 16:25:52

标签: sql-server ruby ruby-on-rails-4

我有一个MSSQL表,其中包含image类型的字段,其中包含一些文本。

该字段的数据如下所示:

54004800490053002000490053002000410020004c00490047004800540041005200540020004f0052004400450052002e00200020004c004900470048005400410052005400200049005300200044004f0049004e004700200054004800450020004600410042002e000d000a004c00490047004800540041005200540020005300480049005000500049004e004700200054004f00200043005500530054004f004d004500520020003c0038002d00320033002d00310037003e000d000a000d000a0043006f006e006e00690065002c00200070006c00650061007300650020007000720069006e007400200073007400690063006b00650072007300200066006f0072002000650061006300680020006f007500740065007200200062006f00780020007400680061007400200069006e0063006c0075006400650073002000740068006500200069006e0066006f003a000d000a0028003100290020006f00660020002800310029000d000a004c004100320020005400680072006500650020004c00610072006700650020000d000a00380036005c0022004c0020007800200036005c002200570020007800200038005c00220048000d000a004e00610074007500720061006c000d000a005000320030003900380031003000350020004d004f0044002000500069007a007a00610020005300750067006100720068006f007500730065002c00200055005400

在PHP中,我可以编写一个SQL查询来转换这些数据:SELECT CAST(CAST(CUST_ORDER_BINARY.BITS as VARBINARY(8000)) as VARCHAR(8000)) as result FROM CUST_ORDER_BINARY WHERE CUST_ORDER_ID = 'CO-299403S';

当我在Ruby中尝试同样的事情时,我会得到这样的结果:

specs = VisualCustomer.connection.exec_query(sql).first

{"result"=>"T\u0000H\u0000I\u0000S\u0000 \u0000I\u0000S\u0000 \u0000A\u0000 \u0000L\u0000I\u0000G\u0000H\u0000T\u0000A\u0000R\u0000T\u0000 \u0000O\u0000R\u0000D\u0000E\u0000R\u0000.\u0000 \u0000 \u0000L\u0000I\u0000G\u0000H\u0000T\u0000A\u0000R\u0000T\u0000 \u0000I\u0000S\u0000 \u0000D\u0000O\u0000I\u0000N\u0000G\u0000 \u0000T\u0000H\u0000E\u0000 \u0000F\u0000A\u0000B\u0000.\u0000\r\u0000\n\u0000L\u0000I\u0000G\u0000H\u0000T\u0000A\u0000R\u0000T\u0000 \u0000S\u0000H\u0000I\u0000P\u0000P\u0000I\u0000N\u0000G\u0000 \u0000T\u0000O\u0000 \u0000C\u0000U\u0000S\u0000T\u0000O\u0000M\u0000E\u0000R\u0000 \u0000<\u00008\u0000-\u00002\u00003\u0000-\u00001\u00007\u0000>\u0000\r\u0000\n\u0000\r\u0000\n\u0000C\u0000o\u0000n\u0000n\u0000i\u0000e\u0000,\u0000 \u0000p\u0000l\u0000e\u0000a\u0000s\u0000e\u0000 \u0000p\u0000r\u0000i\u0000n\u0000t\u0000 \u0000s\u0000t\u0000i\u0000c\u0000k\u0000e\u0000r\u0000s\u0000 \u0000f\u0000o\u0000r\u0000 \u0000e\u0000a\u0000c\u0000h\u0000 \u0000o\u0000u\u0000t\u0000e\u0000r\u0000 \u0000b\u0000o\u0000x\u0000 \u0000t\u0000h\u0000a\u0000t\u0000 \u0000i\u0000n\u0000c\u0000l\u0000u\u0000d\u0000e\u0000s\u0000 \u0000t\u0000h\u0000e\u0000 \u0000i\u0000n\u0000f\u0000o\u0000:\u0000\r\u0000\n\u0000(\u00001\u0000)\u0000 \u0000o\u0000f\u0000 \u0000(\u00001\u0000)\u0000\r\u0000\n\u0000L\u0000A\u00002\u0000 \u0000T\u0000h\u0000r\u0000e\u0000e\u0000 \u0000L\u0000a\u0000r\u0000g\u0000e\u0000 \u0000\r\u0000\n\u00008\u00006\u0000\\\u0000\"\u0000L\u0000 \u0000x\u0000 \u00006\u0000\\\u0000\"\u0000W\u0000 \u0000x\u0000 \u00008\u0000\\\u0000\"\u0000H\u0000\r\u0000\n\u0000N\u0000a\u0000t\u0000u\u0000r\u0000a\u0000l\u0000\r\u0000\n\u0000P\u00002\u00000\u00009\u00008\u00001\u00000\u00005\u0000 \u0000M\u0000O\u0000D\u0000 \u0000P\u0000i\u0000z\u0000z\u0000a\u0000 \u0000S\u0000u\u0000g\u0000a\u0000r\u0000h\u0000o\u0000u\u0000s\u0000e\u0000,\u0000 \u0000U\u0000T\u0000"}

所以数据几乎是&#34;那里。 :)

我已经尝试过gsubing从结果中移除\u0000,但显然不起作用。

**编辑1 **

因此,出于某种原因,将数据从MSSQL转换为ruby会导致某种部分转换。我从来没有从现场获得原始数据,而是得到了#34;半翻译&#34;数据。即使我只是查询它,它仍然像

"T\x00H\x00I\x00S\x00 \x00I\x00S\x00 \x00A\x00...

我试着把它放回去:

s = order_specs.each_byte.map { |b| b.to_s(16) }.join

然后,当我这样做时:

order_specs = s.scan(/.{2}(?=0{2})/).map{|s| s.to_i(16)}.pack("c*").tr("\x02", " ")

我只是得到一个空字符串。 :/

3 个答案:

答案 0 :(得分:0)

s = "54004800490053002000490053002000410020004c00490047004800540041005200540020004f0052004400450052002e00200020004c004900470048005400410052005400200049005300200044004f0049004e004700200054004800450020004600410042002e000d000a004c00490047004800540041005200540020005300480049005000500049004e004700200054004f00200043005500530054004f004d004500520020003c0038002d00320033002d00310037003e000d000a000d000a0043006f006e006e00690065002c00200070006c00650061007300650020007000720069006e007400200073007400690063006b00650072007300200066006f0072002000650061006300680020006f007500740065007200200062006f00780020007400680061007400200069006e0063006c0075006400650073002000740068006500200069006e0066006f003a000d000a0028003100290020006f00660020002800310029000d000a004c004100320020005400680072006500650020004c00610072006700650020000d000a00380036005c0022004c0020007800200036005c002200570020007800200038005c00220048000d000a004e00610074007500720061006c000d000a005000320030003900380031003000350020004d004f0044002000500069007a007a00610020005300750067006100720068006f007500730065002c00200055005400"

<强>代码

puts s.scan(/.{2}(?=0{2})/).map{|s| s.to_i(16)}.pack("c*")

<强>输出

THISISALIGHTARTORDER.LIGHTARTISDOINGTHEFAB.
LIGHTARTSHIINGTOCUSTOMER<8-23-17>

Connie,leaserintstickersforeachouterboxthatincludestheinfo:
(1)of(1)
LA2ThreeLarge
86\"Lx6\"Wx8\"H
Natural
29815MODizzaSugarhouse,UT

注意:某些字符无法打印,因此不会显示在此页面中。有关详细信息,请参阅此答案的编辑页面。

或者,如果用空格替换"\x02"

puts s.scan(/.{2}(?=0{2})/).map{|s| s.to_i(16)}.pack("c*").tr("\x02", " ")

你得到:

THIS IS A LIGHTART ORDER.  LIGHTART IS DOING THE FAB.
LIGHTART SHIING TO CUSTOMER <8-23-17>

Connie, lease rint stickers for each outer box that includes the info:
(1) of (1)
LA2 Three Large 
86\"L x 6\"W x 8\"H
Natural
29815 MOD izza Sugarhouse, UT

答案 1 :(得分:0)

当您检查数据时会发生这种情况,但是当您写入数据时会很好:

示例:

$ ruby -e 'bin = File.read("/bin/ls");p bin; File.open("/tmp/file","w+"){|f| f.write bin}'
"\u007FELF\u0002\u0001\u0001\u0000\u0000\u0000 ...
....
$ md5sum /bin/ls
84b7b042405dfc79f2afe9b12d6b931d  /bin/ls
$ md5sum /tmp/file
84b7b042405dfc79f2afe9b12d6b931d  /tmp/file

所以我们在这里读取二进制文件/bin/ls并将其写入另一个文件/tmp/file,因为校验和是相同的。

答案 2 :(得分:0)

我终于弄明白了。我需要做string.gsub("\u0000", '')

所以,我似乎正确地从MSSQL数据库中获取数据,但是我认为空字节实际上是在抛弃它并被发送到它出现在页面上的前端。我发誓我之前尝试过gsubing,但无论出于什么原因它都没有用。我现在在响应形成之前再次尝试它,现在正在正确发送。