我正在基于 ARM 的调制解调器 Linux 主机上工作,我需要将 bin 文件读取为 8、16 或 32 位数组。我基本上需要加密有问题的文件,并且正在考虑使用随机位序列对这些位进行异或(我不需要非常复杂的系统)。 Linux 主机中没有 C 或 PERL 模块,因此我无法使用它们,因此我需要使用 shell 脚本来完成此操作。谁能给我一些关于如何进行此操作的指示?
答案1
使用tr
(这里是 rot128):
LC_ALL=C tr '\0-\377' '\200-\377\0-\177' < infile > outfile
对于 XOR 123,您需要计算相应的tr
行:
LC_ALL=C tr '\0-\377' '\173\172\171\170\177\176\175\174\163\162\161\160\167\166\165\164\153\152\151\150\157\156\155\154\143\142\141\140\147\146\145\144\133\132\131\130\137\136\135\134\123\122\121\120\127\126\125\124\113\112\111\110\117\116\115\114\103\102\101\100\107\106\105\104\73\72\71\70\77\76\75\74\63\62\61\60\67\66\65\64\53\52\51\50\57\56\55\54\43\42\41\40\47\46\45\44\33\32\31\30\37\36\35\34\23\22\21\20\27\26\25\24\13\12\11\10\17\16\15\14\3\2\1\0\7\6\5\4\373\372\371\370\377\376\375\374\363\362\361\360\367\366\365\364\353\352\351\350\357\356\355\354\343\342\341\340\347\346\345\344\333\332\331\330\337\336\335\334\323\322\321\320\327\326\325\324\313\312\311\310\317\316\315\314\303\302\301\300\307\306\305\304\273\272\271\270\277\276\275\274\263\262\261\260\267\266\265\264\253\252\251\250\257\256\255\254\243\242\241\240\247\246\245\244\233\232\231\230\237\236\235\234\223\222\221\220\227\226\225\224\213\212\211\210\217\216\215\214\203\202\201\200\207\206\205\204'
更一般地说,为了回答这个问题,将文件转换为数字数组,以便 shell 通过标准命令使用:
set -- $(od -An -vtu1 < infile)
然后,您可以应用所需的转换并转换回带有awk
s 的文件printf("%c")
。
但这将是非常低效的。
喜欢:
for i in $(od -An -vtu1 < infile); do
echo "$(($i ^ 123))"
done | awk '{printf "%c", $0}' > outfile
您可以使用od -An -vtu2
, 来获取 16 位数字,但请注意,它采用本地字节顺序,因此在转换回字符时,您必须考虑到这一点。
答案2
您不能在大多数 shell 变量中使用空终止符(或者更确切地说,您可以,但它们将被终止,因为通常它们是这样存储的),因此这是任何二进制读取的一个相当重要的警告。
如果你有xxd
:
xxd -b | awk '{ for(i=2 ; i<=NF-1 ; i++) { print $i } }'
例如:
echo -n mayonnaise | xxd -b | awk '{ for(i=2 ; i<=NF-1 ; i++) { print $i } }'
01101101
01100001
01111001
01101111
01101110
01101110
01100001
01101001
01110011
01100101
答案3
我使用这个非常粗糙的函数对两个 128 字节文件进行异或运算:
one_time_pad() {
asrc="$1"
bsrc="$2"
dst="$3"
atmp="`mktemp`"
btmp="`mktemp`"
hexdump -v -e '1/1 "%02x" " "' "$asrc" > "$atmp"
hexdump -v -e '1/1 "%02x" " "' "$bsrc" > "$btmp"
rm "$dst"
touch "$dst"
for i in `seq 1 128`
do
a=`awk '{print $'$i';}' < "$atmp"`
b=`awk '{print $'$i';}' < "$btmp"`
echo -n -e '\x'`printf "%x" $((0x$a^0x$b))` >> "$dst"
done
}
one_time_pad in1 in2 out
从性能角度来看,这是非常可怕的(它为每个字节调用 awk 两次!)。就我而言,性能根本不是问题。我相信您可以找到更好的方法。