Linux CLI에서 16진수를 바이너리로 변환

Linux CLI에서 16진수를 바이너리로 변환

16개의 16진수로 구성된 줄(각각 631자)이 있는 텍스트 파일이 있습니다 0,1,2,...,9,A,B,...,F. 각 숫자를 해당하는 4자리 숫자 0과 1로 바꾸고 싶습니다. 즉, 0은 0000, 1은 0001, ..., F는 1111로 바꾼 다음 파일을 .bin으로 저장하고 싶습니다. Linux 터미널에서 이 작업을 어떻게 수행합니까?

내 텍스트 파일의 일부 줄은 다음과 같습니다.

85868D6B0FD5F3186DE92A7FC023CC848110FE61E3045B24BD905C8FDF34698794718CB2BAFF2AFC488C07B01510646141290A8FE55BF41F9D5033B13B31473FB4F7E199624370DC9C7587E5FB84B209B104B2BC194243EFC77C479BEA6778C73FB55939CB8654B1EB0B597CEA9507FE5A9636229BE0E7ECA27844D3A4AE16096D9DDC125728A1BF0C3623518311CF7CE629C15EA767E1F6C992106E86D962D47E307AE9F71FE5C6B664820E3D7521D0F783913E8A116BFD42C65FD2E28C9114CF4BFCB8A2AFD9979E7B5EBC7B59C7A31A7C12931D2C794EF5AED991B32560BBEFCC82D3A6AC6D371C7AC6C06DED6BCEFFC3D9E11A17B4738EA2ECF8CDD14805E57C50F973C6832DB94517A71C06E18329694B8CB7F7028730E54F74E27EF35B3D776A7E46A3F187691D460CBFBCD14BAC4AED32E5592AFDAEC5206
6321EB4F15D5F01D2A5F7474AC6FFCD1A8B52E680AC52CA9B500C956FD269DB8107EFCF6EC0B23B2C54B3A727CC53F6793019BF0D95A037485413576E4A0172A597027ED71D6E785430FA4748E164E5290214B01740736C0EC79D286692170B6EFBA21592EC485350F0DC6C635CD3FA7DAED258405C4247BFA68613B5F7CBEC903E16EA2E780D0934F0A2918F837CF0115B3D76AAFD3F37D905F9572D334D959DDD22C37EBA7707A76333A491F79B9C53A7912AEA38ED400949EB9AD9FCEE71765F4F4A2E21C481A509AB6807DDF5374D9A1A4D0C589E628CAA3C6DC9E4A5C1A7EF3C36A4D2231E2C1E856A19B6F7F4DE713D5BE8A4EFA750FB29A34F00754D875C22C2FC981FAECCC7113D1B0D6FF3BCC747852789A662D104DF1A8C90EB4DDFA48502A3BA9AAE70E7229E8A3D6FBBD00C19D99765BAFC9B09D547
2F75AC10A9E20C07DD4686C5706F66EB1AB33ED9DEDAD69079B6EC0C24C8DF24CB1855825D80CD484E5623BB246041D29240720500EA87586CC4CE5A00990EF8B5B7E2A3CF3E997323870499451E7BFA7F23A2208523B84A98DDC0763701C1AB292D854ADA8FB2E060088D7B3436571745DF25182D7F5A646A6F7DD830B9CCC12C37D416882DD7AAA0E8CB2CE50CE33AD1674C0E78E0F171DEC2D087C6CF2E711FAC2548CCB8C0312D59055A0A3A145B402A749F768F637549E0749215B5542BBC9D07EF9416C1BAB1FBEAC4709C458E7C266342908421BC8F67B7E21ED228D13A0F2750C290EFF8CAF7D2AD6D6C2CB12B81570190E1BC555E0CFBA4951BEAD3740D3BEBF2C7BF2AB64C7F046E5B865D85A1411F854906C05785A0A3684EC0F69D9BAB047A9EC17F973E78A92838C73270F97E54CEF4FABAA82876F

답변1

xxd -r -p

예:

sudo apt install xxd
printf 123456789ABCDEF0 | xxd -r -p | od -A n -t x1 -v

다음을 제공합니다:

 12 34 56 78 9a bc de f0

od원시 바이트를 사람이 읽을 수 있는 바이트로 표시합니다. 즉, xxd -r -p우리가 원하는 작업을 수행하고 사람이 읽을 수 있는 바이트를 123456789ABCDEF0해당 원시 바이트로 변환한다는 의미입니다.

Ubuntu 19.04, xxd V1.10에서 테스트되었습니다.

답변2

내 의견을 답변으로 게시하고 "해결됨"으로 표시하세요.

for n in $(cat myfile | tr 'a-f' 'A-F');do echo "obase=2; ibase=16; $n" | bc ;done

글쎄요, 당신이 말한 내용과 제가 이해한 내용을 바탕으로 몇 가지 조언을 드리겠습니다. 첫 번째는 각 16진수 줄을 새로운 이진 줄로 변환하고 각 줄 끝에 개행 문자를 배치합니다. 해결책은 다음과 같습니다.

cat myfile | while read line
do
  len=${#line}
  binline=""
  index=1
  while [ ${index} -le ${len} ]
  do
    hex=$(echo ${line} | cut -c ${index} | tr 'a-f' 'A-F')
    bin=$(echo "obase=2; ibase=16; ${hex}"|bc)
    padbin=$(printf "%04d" ${bin})
    binline="${binline}${padbin}"
    (( index++ ))
  done
  echo ${binline} >> program.bin
done

그리고 제 기억이 맞다면 여러분은 이 바이너리를 임베디드 시스템이나 그와 유사한 프로그램으로 사용하려고 하는 것입니다. 이 경우 개행 문자에 문제가 있을 수 있습니다. 이 경우, 즉 전체 파일을 하나의 거대한 줄로 만들고 싶다면 다음 코드 조각을 사용할 수 있습니다.

cat myfile | while read line
do
  len=${#line}
  index=1
  while [ ${index} -le ${len} ]
  do
     hex=$(echo ${line} | cut -c ${index} | tr 'a-f' 'A-F')
     bin=$(echo "obase=2; ibase=16; ${hex}"|bc)
     printf "%04d" ${bin} >> p2.bin
     (( index++ ))
  done
done

그렇긴 하지만, 16진수 값 파일의 크기가 기가바이트 또는 심지어 수백 메가바이트라면 bash는 불평을 하고 알 수 없는 오류를 던질 수도 있습니다. 따라서 이 입력 파일을 보다 관리하기 쉬운 덩어리로 자르고 하나씩 처리하는 것이 좋습니다.

이해하기 쉽도록 가장 간단한 방법으로 이 스크립트를 작성했음을 참고하시기 바랍니다. 따라서 실행할 때 약간의 성능 저하가 발생합니다. 3개 행을 처리하는 데 약 6초가 걸립니다. 기다림이 참을 수 없다면 최적화하는 것은 당신에게 달려 있습니다.

답변3

016진수 문자열을 2진수 문자열(각각 2개의 16진수로 구성된 8개의 문자 시퀀스 ) 로 변환하려고 한다고 가정하면 1이진수 문자열로 변환하는 대신 다음을 사용합니다 perl.

$ echo 00ffaa | perl -lne 'print unpack "B*", pack"H*", $_'
000000001111111110101010

그리고 xxd:

$ echo 00ffaa | xxd -p -r | xxd -b -g 0 -c 8 | cut -c11-74
000000001111111110101010

답변4

printf를 사용할 수 있습니다:

$ printf '%04d\n' 0
0000

$ printf '%04d\n' 1
0001

또는 POSIX Awk표준 라이브러리:

$ awklib 'BEGIN {print base_conv("F", 16, 2)}'
1111

관련 정보