簡體   English   中英

將存儲為字符串的字節轉換為Perl中的位並進行修改

[英]Convert a byte stored as string into bits in Perl and modify it

我正在嘗試使用Perl腳本執行以下操作:

  • 從存儲為字符串的十六進制數字中提取兩個字符->這將給出一個以字符串形式寫入的字節
  • 將此字節轉換為二進制(如果存在,我必須保留前導零)
  • 更改二進制中的特定位
  • 轉換回十六進制
  • 替換為原始的十六進制數

為此,經過長時間的互聯網研究,我想到了以下幾行:

# Initialize my variable: in my function, this is passed as input
$str = '5B CD 02 01 10';

# Extract the two characters to form a Byte
$OldByte_str = substr($str,0,2); 

# Convert to binary. Supposed to give '0101 1011'
$PDM_OldBits =  ( "Binary: %b\n", $PDM_OldByte );

# Replace two bits.Supposed to give '01**10** 1011'
substr($PDM_OldBit,2,2)= '10';

# Convert back to Bytes. Supposed to give'6B'
$NewByte_str= sprintf("0x%x", stringdecimal(arraystring($PDM_OldBits))); 

# Substitute back into the original Bytes string.
# Supposed to give: '**6B** CD 02 01 10'
substr($str,0,2)= $PDM_NewByte;

有:

sub stringdecimal {
    return unpack("N", pack("B32", substr("0" x 32 . shift, -32)));
}

sub arraystring {
    my $string = join('', @_);
    return $string;
}

但是,沒有轉換為二進制。 因此,我也無法檢查其余的代碼。

作為Perl的初學者,我在這里問這個問題-以防有人對我的問題有一些提示或解決方案。

strictwarnings將始終給您提示,以防萬一。

use strict;
use warnings;

sub stringdecimal {
    # return unpack("N", pack("B32", substr("0" x 32 . shift, -32)));
    return oct("0b" . shift);
}

my $str = '5B CD 02 01 10';   #Initialize my variable:in my function, this is passed as input
my $OldByte_str = substr($str,0,2); #extract the two characters to form a Byte

my $PDM_OldBits =  sprintf( "%b", hex($OldByte_str) );#Convert to binary. Supposed to give '0101 1011'

substr($PDM_OldBits,1,2)= '10';  #Replace two bits.Supposed to give '01**10** 1011'

my $NewByte_str= sprintf("%X", stringdecimal($PDM_OldBits)); #Convert back to Bytes. Supposed to give'6B'

substr($str,0,2)= $NewByte_str; #Substitute back into the original Bytes string.Supposed to give: '**6B** CD 02 01 10'

print $str, "\n";

這是另一種解決方案-僅使用pack()unpack()以及一次對substr()調用(不使用sprintf() )。 它將修改數組中的每個值。 (如果您不希望這樣做,只需取出for()循環,然后將$_替換$_ $bytes[0] 。)

use strict;
use warnings;
use feature('say');

my $str = '5B CD 02 01 10';

my ($orig, $bits, $hex);
my @bytes = split(/ /, $str);
for (@bytes) {
    $bits = unpack('B8', chr(hex($_)));
    $orig = $bits; # for 'debugging'
    substr($bits, 2, 2) = '10';
    say $orig . ' -> ' . $bits;
    $hex = unpack('H2', pack('B8', $bits));
    say $_ . ' -> ' . uc($hex);
}

輸出...

01011011 -> 01101011
5B -> 6b
11001101 -> 11101101
CD -> ed
00000010 -> 00100010
02 -> 22
00000001 -> 00100001
01 -> 21
00010000 -> 00100000
10 -> 20

使用substr($str, 0, 2); 除了笨拙之外,提取感興趣的字節可能不可靠。 例如,如果輸入中的白色間距不一致,則可以提取'B '而不是'5B'' C'而不是'CD' 這就是為什么我使用split()將字符串拆分為字節。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM