当我遇到下面的代码时,我正在尝试制作一个接受两个十进制值并将它们进行异或的XOR密码,我需要帮助理解这实际上是做什么,以及如何使用它来生成我自己的密码。
到目前为止,我已经接受了键和字符串的输入,然后我尝试使用xxd -bi将该字符串转换为二进制,但答案似乎很奇怪,所以我转向了bc,一旦我得到了答案,我可以简单地执行binary(String) ^ key吗
如果不是,正确的方法是什么?
xor() {
key=$1 │
length=${#key} │
while read -r -N1 byte │
do │
char=${key:$((i % length)):1} │
((i++)) │
echo $((byte ^ char)) │
done │
} 发布于 2018-01-22 00:52:20
可能有更简洁的方法来处理字符转换,但在xor函数中,需要将每个xor'ed字符编码为两位十六进制值。这样,您就可以读取编码的字符串并解码每个两位十六进制值。例如:
## endcode string on stdin to 2-digit hex using key
xor() {
local key="$1"
local length=${#key}
while read -r -N1 byte
do
char=${key:$((i % length)):1}
((i++))
printf -v byteval "%d" "'$byte"
printf -v charval "%d" "'$char"
printf "%02x" $((byteval ^ charval))
done
echo""
}(备注: "'$byte"和"'$char"前的单引号前缀,强制文字字符值转换)
解码是比较复杂的。要执行反向xor以获取原始字符串,必须准备一个保存xor结果的格式化十六进制或八进制文字表示的变量(例如,\0num表示八进制,\xnum表示十六进制)。然后,您可以使用这个不带引号的变量作为printf格式的字符串来获取原始字符。示例解码:
## decode 2-digit hex string to text using key
decode() {
local key="$1"
local length=${#key}
local res=
local out=
while read -r -N2 byte
do
char=${key:$((i % length)):1}
((i++))
printf -v byteval "%d" "0x$byte"
printf -v charval "%d" "'$char"
res=$((byteval ^ charval))
printf -v out "\\\x%02x" $((byteval ^ charval))
if [ "$res" -gt '0' ]; then
printf $out
else
printf " "
fi
done
echo""
}(注意:我需要检查空格是否为零值,因为空格被解码为0而不是20。原因是二进制中的' ' (空格)是00100000。注意:第6位是字符串中唯一的1。第6位恰好也对应于小写的位--这意味着如果您设置第6位,则会得到a-z,这意味着对于任何A-Z。因此,如果您使用任何小写字符(例如您的"xyz"密钥) xor一个space,您将失去取回空间的能力)
使用bash,可以使用feed字符串将字符串值提供给每个xor和decode。把这些部分放在一起,你可以这样做:
#!/bin/bash
## endcode string on stdin to 2-digit hex using key
xor() {
local key="$1"
local length=${#key}
while read -r -N1 byte
do
char=${key:$((i % length)):1}
((i++))
printf -v byteval "%d" "'$byte"
printf -v charval "%d" "'$char"
printf "%02x" $((byteval ^ charval))
done
echo""
}
## decode 2-digit hex string to text using key
decode() {
local key="$1"
local length=${#key}
local res=
local out=
while read -r -N2 byte
do
char=${key:$((i % length)):1}
((i++))
printf -v byteval "%d" "0x$byte"
printf -v charval "%d" "'$char"
res=$((byteval ^ charval))
printf -v out "\\\x%02x" $((byteval ^ charval))
if [ "$res" -gt '0' ]; then
printf $out
else
printf " "
fi
done
echo""
}
[ -z "$1" ] && { ## validate key given
printf "error: insufficient input - key\n"
exit 1
}
key="$1"
read -r line ## read input string on stdin
[ -z "$line" ] && { ## validate input string provided
printf "error: no string input on stdin.\n"
exit 1
}
printf "original: %s\n" "$line" ## output original string
encoded=$(xor "$key" <<<$line) ## encode and output encoded string
printf "encoded : %s\n" "$encoded"
decoded=$(decode "$key" <<<"$encoded") ## decode and output decoded string
printf "decoded : %s\n" "$decoded"(备注:我相信有更优雅的方法来处理这个问题)
示例使用/输出
$ echo "I am the string" | bash bashxor.sh xyz
original: I am the string
encoded : 31791b15790e101c7a0b0d0811171d78
decoded : I am the string看一看这件事,如果你有进一步的问题,请告诉我。单独使用Bash并不是执行低级编码/解码的理想平台。如果这不是一个学习练习,那么看看使用openssl提供的工具来完成同样的事情--适当地。
https://stackoverflow.com/questions/48367013
复制相似问题