技术问询:解析给定XOR密码bash函数及自制密码实现方法
先拆解你拿到的bash xor() 函数到底做了什么
首先得先修正原代码里的语法错误——你贴的代码里用了│,这应该是输入时的格式问题,正确可运行的版本是:
xor() { key=$1 length=${#key} i=0 # 原代码漏了初始化i,这是关键bug! while read -r -N1 byte do char=${key:$((i % length)):1} ((i++)) echo $((byte ^ char)) done }
这个函数的核心功能是按ASCII字节对输入流和密钥做循环异或:
- 它接收第一个参数作为加密/解密密钥
- 每次从标准输入读1个字符,自动把字符解析成对应的ASCII十进制值
- 通过
i % length实现密钥的循环复用(也就是流密码里的“密钥流”逻辑,短密钥可以反复加密长文本) - 计算输入字符和密钥字符的ASCII值异或结果,输出十进制数字
如何用它实现你的XOR密码需求
XOR密码的本质是加密和解密完全可逆——因为A ^ B ^ B = A,所以同一个函数既可以加密也可以解密。下面一步步说正确的操作方式:
1. 别再纠结二进制字符串转换了!
你之前用xxd -bi出问题,是因为bash的算术运算只认十进制/十六进制/八进制数字,不认01100001这种二进制字符串。正确的思路是直接用字符的ASCII值做运算,bash会自动帮你完成字符到ASCII值的转换,根本不需要手动转二进制。
2. 加密操作(明文→密文)
假设你的密钥是mysecret,明文是HelloWorld,直接把明文流传给xor函数即可:
# -n 避免echo自动加换行符干扰加密 echo -n "HelloWorld" | xor "mysecret"
输出会是一串十进制数字(比如17 24 15 15 12 27 15 20 21 18),这就是加密后的密文。
3. 解密操作(密文→明文)
把加密得到的十进制数字重新转成字符流,再传给同一个xor函数就能还原明文:
比如先把密文数字存到cipher.txt(每行一个数字),然后执行:
# 把十进制数字转成对应ASCII字符,再传入xor函数解密 while read num; do printf "\\$(printf '%03o' "$num")"; done < cipher.txt | xor "mysecret"
运行后就能输出原明文HelloWorld。
4. 优化:直接输出加密后的字符(更实用)
如果不想输出十进制数字,想直接得到加密后的字符(包括不可打印字符,适合存储),可以修改函数输出为字符:
xor_char() { key=$1 length=${#key} i=0 while read -r -N1 byte do char=${key:$((i % length)):1} ((i++)) # 把异或后的十进制值转成ASCII字符输出 printf "\\$(printf '%03o' $((byte ^ char)))" done }
加密时直接输出到文件:
echo -n "HelloWorld" | xor_char "mysecret" > cipher.bin
解密时直接反向读取文件:
cat cipher.bin | xor_char "mysecret"
关于你问的binary(String) ^ key
bash里没法直接对二进制字符串做异或运算,因为它的算术系统只处理数字类型。所以正确做法就是像上面那样,直接用字符的ASCII十进制值做异或——这也是那个xor函数的核心逻辑,完全符合XOR密码的要求。
内容的提问来源于stack exchange,提问作者Dixon
相关产品推荐
相关产品推荐

