간단히:

간단히:

나는 awk텍스트 파일을 구문 분석하는 데 사용합니다. 텍스트 파일에는 다음과 같은 4바이트 데이터 필드가 있습니다.

11110000  10100000  10110000  10010000

이 필드를 읽고 이진수에서 16진수로 변환하고 싶습니다. 현재 저는 10진수가 printf %x되고 1111000016진수가 됩니다. 이것이 나타내는 값은 11110000xA98760아닙니다 0xF0.

내 코드는 간단하고 BASH와 Linux를 처음 사용합니다.

awk'{printf(%x %x %x %x, $1, $2, $3, $4)};

문자열 필드를 바이너리로 저장한 다음 16진수로 변환하는 방법은 무엇입니까? "bc <<<"obase=16;ibase=2;를 사용하여 터미널에서 16진수를 얻을 수 있습니다. $변수"". 이 스크립트를 작성하려고 하면 구문 오류가 발생합니다.

답변1

awk10진수, 8진수, 16진수만 지원되며, 2진수는 지원되지 않습니다. 당신이 사용할 수있는 perl:

perl -lane 'BEGIN{$, = " "} print unpack "(H2)*", pack("(B8)4", @F)'

dcGNU 의 경우 tac(일부 시스템도 참조 tail -r):

{ echo 16o2i; cat; echo f; } < file.txt | dc | tac

사용 (구문 오류가 bc// / 의 최신 버전이 아닌 셸에서 사용된 연산자와 관련이 있다고 가정)<<< zshzshbashksh93mkshyash

{ echo 'obase=16; ibase=2'; tr -cs 01 '[\n*]'; } < file.txt | bc

답변2

이것은 우아하지 않은 해킹이지만 작동합니다. 숫자의 이진 표현을 취하고 십진수 값을 반환하는 함수 b를 선언합니다. 그런 다음 %x를 사용하여 printf16진수로 표시됩니다.

$ awk 'func b(i, t,a,c){a=1;for(c=length(i);c>0;c--){t+=substr(i,c,1)=="1"?a:0;a*=2}return t}{printf "0x%x 0x%x 0x%x 0x%x\n",b($1),b($2),b($3),b($4)}' bin.txt
0xf0 0xa0 0xb0 0x90

답변3

perl -pale '$_ = join $", map { sprintf "%X", oct "0b$_" } @F'

간단히:

Perl options:
     -p => autoprint + implcit file read in/line, a.la., awk
     -a => autosplit line into fields using default delimiter ' '
     -l => ORS=IRS="\n"

Perl standard variables:
      $" => list separator, by default it is a single space " "
      $_ => refers to the whole line, equivalent to $0 in awk
      @F => fields got by splitting the current line, $1, $2,$3, ... $NF in awk

Perl code:
      map { body } list_of_items
           Map takes in an input list and applies the code present in 
           it's body on each element of this list to generate an output list.
      join <separator>, <list>
           Join takes in an input list and joins their elements by the 
           separator provided in the first argument.

       oct <number>
            When the input to this function is prefixed by a "0b", then
            it is treated to be a binary number and outputs the decimal
            equivalent.

       sprintf "%x" <decimal>
             This function whose format is "%x" treats the input as
             decimal and returns the equivalent number in hex.

답변4

대상 시스템에 GNU Bash가 있는 경우 산술 표현식에서 8진수 및 16진수 이외의 진수에 대한 지원을 활용할 수 있습니다. 예를 들어:

bash$ echo $(( 2#1011 | 2#1100 ))   # bitwise OR of 11 and 12
15

좋아요, 이 데이터를 얻으면:

11110000  10100000  10110000  10010000

그리고 어떻게든 이 문법에 맞춰서 평가해 보세요.

$(( 2#11110000101000001011000010010000 ))

우리는 가치를 얻었습니다

4037062800

(예, 이는 32비트 bash 버전에서 작동하며 부정적인 결과를 얻지 못합니다.)

우리는 이것을 아주 간단하게 할 수 있습니다:

echo $(( 2#$(tr -d ' ' < file) ))
4037062800

유일한 문제는 모든 것이 eval어떤 방식으로든 위장되어 있다는 것입니다. 파일 내용을 기반으로 명령의 출력을 표현식에 삽입한 다음 평가합니다. file신뢰할 수 없는 출처에서 얻은 경우 보안 위험이 있을 수 있습니다. 예를 들어, 나는 file인터넷 사용자가 제출한 양식의 POST 데이터를 포함하는 Apache의 CGI 스크립트에 이를 넣지 않을 것입니다 .

관련 정보