
instructions.txt
내용이 포함된 파일이 있습니다 .
00000000000000000000000000010011
00000010110100010010000010000011
00000000011100110000001010110011
00000000011100110000010000110011
00000000011100110110010010110011
00000000000000000000000000010011
.instructions.bin
instructions.txt
즉, .bin
파일은 파일에 있는 것과 동일한 192비트 .txt
(라인당 32비트)여야 합니다. 우분투 리눅스에서 bash를 사용하고 있습니다. 사용하려고 했는데 xxd -b instructions.txt
출력이 192비트보다 훨씬 깁니다.
답변1
oneliner는 1과 0으로 구성된 32비트 문자열을 해당 바이너리로 변환합니다.
$ perl -ne 'print pack("B32", $_)' < instructions.txt > instructions.bin
그것이 하는 일:
perl -ne
instructions.txt
STDIN( ) 에 제공된 입력 파일의 각 줄을 반복합니다.pack("B32", $_)
32비트의 문자열 목록($_
STDIN에서 방금 읽음)을 가져와 이진 값으로 변환합니다("b32"
내림차순 비트 순서 대신 각 바이트 내에서 오름차순 비트 순서를 원하는 경우 대안으로 사용할 수 있습니다.perldoc -f pack
자세한 내용은 참조).print
그런 다음 변환된 값을 STDOUT으로 출력하고 이진 파일로 리디렉션합니다.instructions.bin
확인하다:
$ hexdump -Cv instructions.bin
00000000 00 00 00 13 02 d1 20 83 00 73 02 b3 00 73 04 33 |...... ..s...s.3|
00000010 00 73 64 b3 00 00 00 13 |.sd.....|
00000018
$ xxd -b -c4 instructions.bin
00000000: 00000000 00000000 00000000 00010011 ....
00000004: 00000010 11010001 00100000 10000011 .. .
00000008: 00000000 01110011 00000010 10110011 .s..
0000000c: 00000000 01110011 00000100 00110011 .s.3
00000010: 00000000 01110011 01100100 10110011 .sd.
00000014: 00000000 00000000 00000000 00010011 ....
답변2
-r
옵션(역방향 모드) 을 추가 하면 실제로 의도한 대로 작동하지 않습니다. xxd는 단순히 이 두 플래그 결합을 지원하지 않기 때문입니다( 둘 다 제공되면 xxd -b
무시합니다 ). -b
대신, 먼저 비트를 16진수로 직접 변환해야 합니다. 예를 들면 다음과 같습니다.
( echo 'obase=16;ibase=2'; sed -Ee 's/[01]{4}/;\0/g' instructions.txt ) | bc | xxd -r -p > instructions.bin
전체 설명:
- 괄호 안의 부분이
bc
스크립트를 생성합니다. 먼저 입력 기수를 2진수(2)로 설정하고 출력 기수를 16진수(16)로 설정합니다. 그 후, 명령은 16진수에 해당하는 4비트의 각 그룹 사이에 세미콜론을 사용하여sed
내용을 인쇄합니다 .instructions.txt
결과는 으로 파이프됩니다bc
. - 세미콜론은 의 명령 구분 기호
bc
이므로 스크립트가 수행하는 모든 작업은 모든 입력 정수를 다시 인쇄하는 것입니다(기본 변환 후). - 의 출력
bc
은 일련의 16진수이며 일반적인xxd -r -p
.
산출:
$ hexdump -Cv instructions.bin
00000000 00 00 00 13 02 d1 20 83 00 73 02 b3 00 73 04 33 |...... ..s...s.3|
00000010 00 73 64 b3 00 00 00 13 |.sd.....|
00000018
$ xxd -b -c4 instructions.bin
00000000: 00000000 00000000 00000000 00010011 ....
00000004: 00000010 11010001 00100000 10000011 .. .
00000008: 00000000 01110011 00000010 10110011 .s..
0000000c: 00000000 01110011 00000100 00110011 .s.3
00000010: 00000000 01110011 01100100 10110011 .sd.
00000014: 00000000 00000000 00000000 00010011 ....
답변3
나의원래 답변잘못되었습니다. 또는 ... 중 xxd
하나를 수락할 수 없습니다 .-p
-r
-b
다른 답변이 실행 가능하고 "또 다른 방법", 다음은 어떻습니까?
입력
$ cat instructions.txt
00000000000000000000000000010011
00000010110100010010000010000011
00000000011100110000001010110011
00000000011100110000010000110011
00000000011100110110010010110011
00000000000000000000000000010011
산출
$ hexdump -Cv < instructions.bin
00000000 00 00 00 13 02 d1 20 83 00 73 02 b3 00 73 04 33 |...... ..s...s.3|
00000010 00 73 64 b3 00 00 00 13 |.sd.....|
00000018
배시 파이프라인:
cat instructions.txt \
| tr -d $'\n' \
| while read -N 4 nibble; do
printf '%x' "$((2#${nibble}))"; \
done \
| xxd -r -p \
> instructions.bin
cat
- 불필요하지만 명확성을 위해 사용됨tr -d $'\n'
- 입력에서 모든 개행 문자를 제거합니다.read -N 4 nibble
- 읽다정확히nibble
변수 에 4× 문자printf '%x' "$((2#${nibble}))"
니블을 바이너리에서 1× 16진수 문자로 변환$((2#...))
- 주어진 값을 2진수(2진수)에서 10진수(10진수)로 변환합니다.printf '%x'
- 주어진 값을 10진수(10진수)에서 16진수(16진수)로 형식화합니다.
xxd -r -p
- 역방향(-r
) 일반 덤프(-p
) - 16진수에서 원시 바이너리로
파이썬:
python << EOF > instructions.bin
d = '$(cat instructions.txt | tr -d $'\n')'
print(''.join([chr(int(d[i:i+8],2)) for i in range(0, len(d), 8)]))
EOF
- 인용되지 않은heredoc(
<< EOF
)는 콘텐츠를 Python 코드로 가져오는 데 사용됩니다.- 입력이 커지면 효율적이지 않습니다.
cat
tr
- 깨끗한(한 줄) 입력을 얻는 데 사용됩니다 .range(0, len(d), 8)
- 0부터 문자열 끝까지의 숫자 목록을d
한 번에 8×씩 단계별로 가져옵니다.chr(int(d[i:i+8],2))
- 현재 조각(d[i:i+8]
)을 이진수에서 십진수(int(..., 2)
)로 변환한 다음 원시 문자(chr(...)
) 로 변환합니다.[ x for y in z]
-목록 이해''.join(...)
- 문자 목록을 단일 문자열로 변환합니다.print(...)
- 인쇄해 보세요
답변4
바이너리 파일은 새 줄 문자로 줄을 구분하지 않습니다. 바이너리 파일에는 구분 기호가 없습니다. 이는 0과 1이 여러 개 있는 하나의 파일일 뿐이며, 의미를 부여하기 위해 파일 할당 테이블이나 유사한 매핑으로 제어되는 섹터에 배열된 일부 장치에 저장됩니다.
텍스트 파일을 있는 그대로 변환하여 192비트(24바이트)가 되는 바이너리로 변환하거나 각 32비트 시퀀스 뒤에 개행 문자를 추가하여 6바이트의 추가 바이트가 있는 파일을 제공할 수 있습니다.
아래 코드는 요청에 따라 192비트 파일을 제공합니다.
for x in $(cat file.txt);
do s=${x:0:32};
echo $(printf '%08X' "$((2#$s))");
done | xxd -r -p > file.bin
패딩을 위한 추가 코드를 원하지 않는 경우 대안은 한 번에 8비트를 읽는 것입니다(텍스트 파일의 4바이트 라인).
우분투 16.04.7에서 테스트되었습니다.