如何在 Perl 中将字符串转换为十六进制(每个字符 16 位)

问题描述 投票:0回答:3

我阅读了这篇文章如何在 Perl 中将十六进制数转换为字符字符串 将十六进制数转换为字符串。

如何进行反向操作?我需要在 Perl 中将字符串转换为十六进制。例如,我有一个字符串“hello world!”(应该是“Hello,World!”),我必须得到:

00680065006C006C006F00200077006F0072006C00640021
perl
3个回答
12
投票

这是另一种方法。使用正则表达式一次性完成这一切。

my $string = 'hello world!';
$string =~ s/(.)/sprintf '%04x', ord $1/seg;

7
投票

可用于执行此操作的一种算法是:

  • 将字符串分解为字符
  • 将字符转换为其数值(另请参阅ASCIIperlunicode
  • 以 10 为基数的数字转换为四位十六进制数
  • 将其粘回一起和/或输出

可能的实施方案是

print map { sprintf '%04X', ord } split //, 'hello world!';

该程序的输出是

00680065006C006C006F00200077006F0072006C00640021

也就是说,可能有一个我不知道的

pack
实现。


7
投票

你似乎想要

use Encode qw( encode );

my $text = 'hello world!';
my $hex = uc unpack 'H*', encode 'UTF-16be', $text;

解释如下。


现有答案提供了 Unicode 代码点的十六进制表示。

该格式不允许输入包含任何高于 0xFFFF 的字符。如果允许的话,就没有任何办法知道是否

20000200002000020000

意味着

2000 0200 0020 0002 0000

20000 20000 20000 20000

如果没问题,因为你永远不会有大于 0xFFFF 的字符,那么我建议如下:

my $text = 'hello world!';
my $hex = uc unpack 'H*', pack 'n*', unpack 'W*', $text;

它应该比现有的解决方案快得多,并且它比现有的解决方案更好地处理 0xFFFF 以上的字符(因为它仍然只为 0xFFFF 以上的字符提供四个十六进制数字)。


但是,如果您想要处理所有 Unicode 代码点,则上述解决方案和早期答案提供的解决方案还不够。

考虑到这一点,我怀疑您实际上想要 Unicode 代码点的 UTF-16BE 编码的十六进制表示。最糟糕的是,具有高于 0xFFFF 的字符仍会产生有用且无损的输出。

Code point    Perl string lit  JSON string lit  Hex of UCP  Hex of UTF-16be
------------  ---------------  ---------------  ----------  ---------------
h  (U+0068)   "\x{68}          "\u0068"         0068        0068
é  (U+00E9)   "\x{E9}          "\u00E9"         00E9        00E9
ጀ  (U+1300)   "\x{1300}        "\u1300"         1300        1300
𠀀 (U+20000)  "\x{20000}       "\uD840\uDC00"   20000       D840DC00

如果是这样的话,你想要

use Encode qw( encode );

my $text = 'hello world!';
my $hex = uc unpack 'H*', encode 'UTF-16be', $text;
© www.soinside.com 2019 - 2024. All rights reserved.