简体   繁体   English

如何将十六进制转换为十六进制字符串

[英]How to convert hex to string of hex

I have a problem understanding and using the 'vec' keyword. 我在理解和使用'vec'关键字时遇到问题。

I am reading a logpacket in which values are stored in little endian hexadecimal. 我正在读取一个日志包,其中的值以小尾数十六进制存储。 In my code, I have to unpack the different bytes into scalars using the unpack keyword. 在我的代码中,我必须使用unpack关键字将不同的字节解压缩为标量。

Here's an example of my problem: 这是我的问题的一个例子:

my @hexData1 = qw(50 65);
my $data = pack ('C*', @hexData1);
my $x = unpack("H4",$data);    # At which point the hexadecimal number became a number 
print $x."\n";
#my $foo = sprintf("%x", $foo);

print "$_-> " . vec("\x65\x50", $_, 1) . ", " for (0..15);    # This works.
print "\n";

But I want to use the above statement in the way below. 但是我想以下面的方式使用上面的语句。 I don't want to send a string of hexadecimal in quotes. 我不想在引号中发送十六进制字符串。 I want to use the scalar array of hex $x. 我想使用十六进制$ x的标量数组。 But it won't work. 但这是行不通的。 How do I convert my $x to a hexadecimal string. 如何将$ x转换为十六进制字符串。 This is my requirement. 这是我的要求。

print "$_-> " . vec($x, $_, 1).", " for (0..15);    # This doesn't work.
print "\n";

My final objective is to read the third bit from the right of the two byte hexadecimal number. 我的最终目标是从两个字节的十六进制数字的右边读取第三位。

How do I use the 'vec' command for that? 我该如何使用“ vec”命令?

You are making the mistake of unpack ing $data into $x before using it in a call to vec . 您犯了将$ data unpack$x然后再调用vec vec expects a string, so if you supply a number it will be converted to a string before being used. vec需要一个字符串,因此,如果提供一个数字,它将在使用前转换为字符串。 Here's your code 这是你的代码

my @hexData1 = qw(50 65);
my $data= pack ('C*', @hexData1);

The C pack format uses each value in the source list as a character code. C pack格式使用源列表中的每个值作为字符代码。 It is the same as calling chr on each value and concatenating them. 这与对每个值调用chr并将它们串联在一起相同。 Unfortunately your values look like decimal, so you are getting chr(50).chr(65) or "2A" . 不幸的是,您的值看起来像十进制,因此您得到的是chr(50).chr(65)"2A" Since your values are little-endian, what you want is chr(0x65).chr(0x50) or "\\x65\\x50" , so you must write 由于您的值是小尾数,因此您想要的是chr(0x65).chr(0x50)"\\x65\\x50" ,因此您必须编写

my $data= pack ('(H2)*', reverse @hexData1);

which reverses the list of data (to account for it being little-endian) and packs it as if it was a list of two-digit hex strings (which, fortunately, it is). 这会反转数据列表(以解决这个问题,因为它是低端字节序),并将其打包为好像是两位十六进制字符串的列表一样(幸运的是,它是)。

Now you have done enough. 现在您已经完成了。 As I say, vec expects a string so you can write 正如我所说, vec需要一个字符串,以便您可以编写

print join ' ', map vec($data, $_, 1), 0 .. 15;
print "\n";

and it will show you the bits you expect. 它会向您显示您期望的位。 To extract the the 3rd bit from the right (assuming you mean bit 13, where the last bit is bit 15) you want 要从右侧提取第3位 (假设您的意思是13位,最后一位是15位),

print vec $data, 13, 1;

First, get the number the bytes represent. 首先,获取字节代表的数字。

If you start with "\\x50\\x65", 如果您以“ \\ x50 \\ x65”开头,

my $num = unpack('v', "\x50\x65");

If you start with "5065", 如果您以“ 5065”开头,

my $num = unpack('v', pack('H*', "5065"));

If you start with "50","65", 如果您以“ 50”,“ 65”开头,

my $num = unpack('v', pack('H*', join('', "50","65"));

Then, extract the bit you want. 然后,提取所需的位。

If you want bit 10, 如果要第10位

my $bit = ($num >> 10) & 1;

If you want bit 2, 如果要位2

my $bit = ($num >> 2) & 1;

(I'm listing a few possibilities because it's not clear to me what you want.) (我列出了一些可能性,因为我不清楚您想要什么。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM