ハッシュ関数をテストする必要がありますが、特定のファイルの1ビットだけを変更したいと思います。
ddコマンドを使ってみました。これはうまくいきますが、わずかではなくバイト全体のみを変更できます。
sudo dd if=/dev/zero of=/file.bin bs=1 seek=10 count=1 conv=notrunc
また、正規表現を使ってsedコマンドを試しましたが、ファイルの内容がわからないため、「a」を「b」に変更することはできません。
これを行うコマンドを知っている人はいますか?
答え1
sed
ファイルにヌル値を含めることができるため、テキスト指向フィルタは失敗します。ただし、perl
またはなどのNULL値を処理できるプログラミング言語を使用できますpython
。これがPython 3ソリューションです。読みやすくするために必要なものよりも数行長くなります。
#!/usr/bin/env python3
"""Toggle the bit at the specified offset.
Syntax: <cmdname> filename bit-offset"""
import sys
fname = sys.argv[1]
# Convert bit offset to bytes + leftover bits
bitpos = int(sys.argv[2])
nbytes, nbits = divmod(bitpos, 8)
# Open in read+write, binary mode; read 1 byte
fp = open(fname, "r+b")
fp.seek(nbytes, 0)
c = fp.read(1)
# Toggle bit at byte position `nbits`
toggled = bytes( [ ord(c)^(1<<nbits) ] )
# print(toggled) # diagnostic output
# Back up one byte, write out the modified byte
fp.seek(-1, 1) # or absolute: fp.seek(nbytes, 0)
fp.write(toggled)
fp.close()
ファイル(たとえばbitflip
)に保存して実行可能にし、変更したいファイル名とオフセットで実行します。ビット単位で。ファイルをその場で修正します。同じオフセットで2回実行すると、ファイルが回復します。
答え2
コツはないようです。以下は簡単なスクリプトです。 " flipbit
"として保存してください。
#!/usr/bin/perl
# Arguments: byte (starting from 0), bit (0-7), filename (otherwise stdin)
$byte = shift(@ARGV);
$bit = shift(@ARGV);
undef $/;
$file=<>;
substr($file,$byte,1) = substr($file,$byte,1) ^ chr(1<<$bit);
print $file;
テスト:
$ echo abb | ~/bin/flip-bit.pl 2 0 | od -xa
0000000 6261 0a63
a b c nl
これにより、3番目の文字の下位ビット(0)が反転され、「b」が「c」に変わります。
1行のコマンドで:
perl -e '$byte=shift(@ARGV);$bit=shift(@ARGV);undef $/; $file=<>; substr($file,$byte,1) = substr($file,$byte,1) ^ chr(1<<$bit); print $file'
答え3
ついに解決策を見つけxxd
ましたdd
。
a=$(xxd -b -l 1 -seek 3 -p a.bin);b=1;echo -e "\x$((${a}^${b}))" | dd of=a.bin bs=1 seek=3 count=1 conv=notrunc
hexdump a.bin v
0000000 61 39 73 36 36 64 66 38 61 39 73 64 35 36 66 35
0000010 37 61 73 64 37 66 74 75 61 67 73 0a 61 73 64 66
hexdump b.bin v
0000000 61 39 73 37 36 64 66 38 61 39 73 64 35 36 66 35
0000010 37 61 73 64 37 66 74 75 61 67 73 0a 61 73 64 66
しかし、醜いです。
答え4
head
、を使用したtail
簡単なソリューションですxxd
。次の例では、最後のバイトの最下位ビットを反転します。ファイル。空。
head -c -1 file.bin > flipped.bin
LAST=`tail -c 1 file.bin | xxd -ps`
printf "%02X" $(( $((16#$LAST)) ^ 1 )) | xxd -r -ps >> flipped.bin