如何将perl中的十六进制字符串转换为ascii?

irlmq6kh  于 2022-11-15  发布在  Perl
关注(0)|答案(1)|浏览(170)

我有一个旧的遗留系统,它从数据库中提取postgres bytea数据(在编译时不能更改代码)。我如何将这种格式的bytea数据转换为ascii字符串呢?
以下是数据示例:

my($value) = "\x46726f6d3a20224d";

我在网上找到了这个例子来解码一个十六进制字符串,但是输入必须以0x开始,而不是\x。如果我把测试字符串从\x改为0x,那么这个例子就可以工作了,但是\x把下一个十六进制46当作大写的F,因为它在做正则表达式匹配,那么剩下的就无法解码了。
下面是我找到的正则表达式,它可以处理以0x开头的字符串,但不能处理\x,有可能以某种方式解码这种类型的十六进制字符串吗?

$value =~ s/0x(([0-9a-f][0-9a-f])+)/pack('H*', $1)/ie;
print $value, "\n";

更正在输入字符串上使用0x时的输出:
发件人:“M
对输入字符串使用\x时输出不正确(未解码):
F726f6d3a20224d型发动机
干杯,迈克

hgqdbh6s

hgqdbh6s1#

假设你真的有字符串

\x46726f6d3a20224d

如由

my $value = "\\x46726f6d3a20224d";

然后,您只需要将0替换为\\即可。

$value =~ s/\\x(([0-9a-f][0-9a-f])+)/pack('H*', $1)/ie;

更好(较少重复,避免了ß相关的减速):

$value =~ s/\\x((?:[0-9a-fA-F]{2})+)/ pack( 'H*', $1 ) /e;

如果您希望这是整个字符串,那么我将使用

$value = pack( 'H*', $value =~ s/^\\x//r );

下面的方法速度更快,但会丢失一些验证:

$value = pack( 'H*', substr( $value, 2 ) );

相关问题