例如,我想将文本字符串或数字输入转换为二进制
输入文字 = 大家好
输出 = 011010000110100100100000011000010110110001101100
1 位文本 -> 8 位二进制
我发现一个 Perl 脚本可以将文本转换为二进制,但不能有效地执行相反的操作(大多数时候)。我已经手动检查了每个步骤,错误出现在
ciphertext=$(echo $ciphertext_bin | perl -lpe '$_=pack"B*",$_')
步骤。有错误或者有更好的方法吗>
#!/bin/bash
##Message
#Ask for Input
echo -n "Enter your message:"
read plaintext
#ASCII to Binary Conversion
plaintext_bin=$(echo "$plaintext" | perl -lpe '$_=unpack"B*"')
#Count chars
plaintext_size=${#plaintext}
plaintext_bin_size=${#plaintext_bin}
##One Time Pad
#Generate Random Sequence
key=$(tr -dc A-Za-z0-9 </dev/urandom | head -c $plaintext_size;)
echo key is $key
#ASCII to Binary Conversion
key_bin=$(echo $key | perl -lpe '$_=unpack"B*"')
##CipherText
# plaintext_bin -||XOR||- key_bin
for ((i=0; i < $plaintext_bin_size; i++)); do
byte=$(( ${plaintext_bin:i:1} ^ ${key_bin:i:1} ))
ciphertext_bin=$ciphertext_bin$byte
done
ciphertext=$(echo $ciphertext_bin | perl -lpe '$_=pack"B*",$_')
echo ciphertext is $ciphertext
我知道您需要字符串变量中字节的
base2
表示形式。
一个简单的方法是使用一些 Python/Perl 库来完成任务,但如果您需要 POSIX 解决方案,那么您可以使用这个
awk
:
bytes_to_base2() {
LANG=C awk -v OFS=, '
BEGIN {
split("0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111", arr)
for (i = 0; i < 256; i++)
base2[ sprintf("%c", i) ] = arr[int(i/16)+1] arr[(i%16)+1]
for (i = 1; i < ARGC; i++) {
len = length(ARGV[i])
for (j = 1; j <= len; j++)
printf("%s", base2[substr(ARGV[i], j, 1)])
print ""
}
}
' "$@"
}
bytes_to_base2 'hi all' 'hello world'
011010000110100100100000011000010110110001101100
0110100001100101011011000110110001101111001000000111011101101111011100100110110001100100
上面的方法很简单:首先创建一个数组,将“byte”转换为其base 2中的8位表示形式,然后转换作为参数传递的字符串的所有字节。
备注: 你或许可以用
od
和 bc
来解决一些问题,但感觉不会更容易。