PEMBARUAN (dengan melihat ke belakang): ... Pertanyaan / jawaban ini (jawaban saya) membuat saya berpikir tentang anjing yang terus mengejar mobil .. Suatu hari, akhirnya, dia mengejar ke mobil .. Oke, dia menangkapnya, tapi dia benar-benar tidak bisa berbuat banyak dengan itu ... Anser ini 'menangkap' string, tetapi kemudian Anda tidak bisa berbuat banyak dengan mereka, jika mereka telah menanamkan null-byte ... (jadi +1 besar untuk Gilles menjawab .. bahasa lain mungkin ada di sini.)
dd
membaca setiap dan semua data ... Ini tentu tidak akan menghalangi nol sebagai "panjang" ... tetapi jika Anda memiliki \ x00 di mana pun dalam data Anda, Anda harus kreatif bagaimana Anda menanganinya;dd
tidak memiliki masalah dengan itu, tetapi skrip shell Anda akan memiliki masalah (tapi itu tergantung pada apa yang ingin Anda lakukan dengan data) ... Berikut ini pada dasarnya output setiap "string data", ke file dengan garis pembagi antara setiap strin ...
btw: Anda mengatakan "karakter", dan saya berasumsi maksud Anda "byte" ...
tetapi kata "karakter" telah menjadi ambigu pada zaman UNICODE, di mana hanya set karakter ASCII 7-bit yang menggunakan byte tunggal per karakter ... Dan bahkan dalam sistem Unicode, jumlah byte bervariasi tergantung pada metode pengkodean karakter , misalnya. UTF-8, UTF-16, dll.
Berikut ini adalah skrip sederhana untuk menyoroti perbedaan antara "karakter" Teks dan byte.
STRING="௵"
echo "CHAR count is: ${#STRING}"
echo "BYTE count is: $(echo -n $STRING|wc -c)"
# CHAR count is: 1
# BYTE count is: 3 # UTF-8 ecnoded (on my system)
Jika karakter panjang Anda adalah 1 byte panjang dan menunjukkan panjang byte , maka skrip ini harus melakukan trik, bahkan jika data berisi karakter Unicode ... dd
hanya melihat byte terlepas dari pengaturan lokal apa pun ...
Skrip ini digunakan dd
untuk membaca file biner dan menampilkan string yang dipisahkan oleh pembagi "====" ... Lihat skrip berikutnya untuk data pengujian
#
div="================================="; echo $div
((skip=0)) # read bytes at this offset
while ( true ) ; do
# Get the "length" byte
((count=1)) # count of bytes to read
dd if=binfile bs=1 skip=$skip count=$count of=datalen 2>/dev/null
(( $(<datalen wc -c) != count )) && { echo "INFO: End-Of-File" ; break ; }
strlen=$((0x$(<datalen xxd -ps))) # xxd is shipped as part of the 'vim-common' package
#
# Get the string
((count=strlen)) # count of bytes to read
((skip+=1)) # read bytes from and including this offset
dd if=binfile bs=1 skip=$skip count=$count of=dataline 2>/dev/null
ddgetct=$(<dataline wc -c)
(( ddgetct != count )) && { echo "ERROR: Line data length ($ddgetct) is not as expected ($count) at offset ($skip)." ; break ; }
echo -e "\n$div" >>dataline # add a newline for TEST PURPOSES ONLY...
cat dataline
#
((skip=skip+count)) # read bytes from and including this offset
done
#
echo
keluar
Skrip ini membuat data uji yang mencakup awalan 3-byte per baris ...
Awalan adalah karakter Unicode tunggal berkode UTF-8 ...
# build test data
# ===============
prefix="௵" # prefix all non-zero length strings will this obvious 3-byte marker.
prelen=$(echo -n $prefix|wc -c)
printf \\0 > binfile # force 1st string to be zero-length (to check zero-length logic)
( lmax=3 # line max ... the last on is set to 255-length (to check max-length logic)
for ((i=1;i<=$lmax;i++)) ; do # add prefixed random length lines
suflen=$(numrandom /0..$((255-prelen))/) # random length string (min of 3 bytes)
((i==lmax)) && ((suflen=255-prelen)) # make last line full length (255)
strlen=$((prelen+suflen))
printf \\$((($strlen/64)*100+$strlen%64/8*10+$strlen%8))"$prefix"
for ((j=0;j<suflen;j++)) ; do
byteval=$(numrandom /9,10,32..126/) # output only printabls ASCII characters
printf \\$((($byteval/64)*100+$byteval%64/8*10+$byteval%8))
done
# 'numrandom' is from package 'num-utils"
done
) >>binfile
#