使用Perl将ASCII中的十六进制字符串转换为相同的十六进制值

3

我在Perl中有一个作为ASCII字符串的十六进制值:

42dc3f74212c4e74bab2 <-- 这是一个字符串,但也是我需要的实际十六进制值。

我需要将其转换为十六进制,通过转换我意味着 \x42\xdc\x3f 等等。

$auth_key = pack("h*", $key); #它有点起作用,但它给出了一个低四位,所以我最终得到的是 24 cd f3,等等。

如何将此字符串转换为相同值的十六进制!

如果可以的话,我正在尝试将其馈入UDP套接字。


顺便说一下:$key = "\x42\xdc\x3f\x74\x21\x2c\x4e\x74\xba\xb2";工作得很好... - user4337675
2个回答

3

请使用pack 'H*', $key

来自于perldoc -fpack

h  A hex string (low nybble first).
H  A hex string (high nybble first).

这是来自shell的一些输出:
$perl -E'print pack "H*","42dc3f74212c4e74bab2"' | hd
00000000  42 dc 3f 74 21 2c 4e 74  ba b2                    |B.?t!,Nt..|
0000000a

1
@GlenBizeau 实际上,它是一样的。除非你在处理插值。 - TLP
1
要么你没有使用pack "H*"(例如由于一个构造错误的shell命令),要么你同时改变了其他东西。 - ikegami
1
如果你把它改回 ",它还能正常工作吗?如果它能正常工作,我会感到惊讶。 - TLP
1
@TLP 我把它改回来了,现在两种方式都可以工作了。这很奇怪,我已经用 Perl 编程大约 20 年了,非常喜欢它。不过这是我第一次尝试使用 PACK 和 UNPACK,以前从未涉及过底层网络编程。我本来以为只是改了引号 ",但是改回去后它仍然能正常工作,所以我不确定了。我盯着那个问题看了几个小时,想知道为什么它不起作用。我知道它应该可以工作,特别是当 h* 给我低位字节时,所以 H* 应该按照正确的方式处理,但是唉... 现在我们永远不会知道了 :) 谢谢你们两个给予的见解,有时候多一些眼睛确实有帮助。 - user4337675
请注意,在小端架构上,perl -e 'print pack "H*","42dc3f74"' | hd 可能会产生 0000000 dc42 743f 的输出,但这是由于 hd 输出的小端16位结果造成的。然而,pack 的结果是正确的且符合预期的。为了更清晰地显示,请使用 hd -t xc - MattTT
显示剩余4条评论

3

另一种方法:

use strict;
use warnings;
use 5.016;

my $str = "42dc3f74212c4e74bab2";
$str =~ s/(..)/chr(hex($1))/eg;  #hex() -> convert hex string to decimal number, chr() -> convert decimal number to a character(string).
say $str;

say (pack "H*","42dc3f74212c4e74bab2");

--output:--
B??t!,Nt??
B??t!,Nt??

使用hexdump进行往返转换:

$ perl -E'print "42dc3f74212c4e74bab2" =~ s/(..)/chr(hex($1))/erg' | hexdump -C
00000000  42 dc 3f 74 21 2c 4e 74  ba b2                    |B.?t!,Nt..|
0000000a

pack() / unpack()非常高效,因此应优先使用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接