如何修复Bash中仿射解密无法还原原文的问题?
修复Bash版Affine解密脚本的方案
问题出在哪
- 密钥a不符合规则:Affine密码要求密钥
a必须和字母表长度m=26互质(两者最大公约数为1),你用的a=4和26的最大公约数是2,不满足条件。这会导致加密不是一一映射关系,解密根本无法得到唯一的原始文本,甚至直接触发计算错误。 - 解密脚本逻辑错误:报错“a / m: division by 0”说明脚本里用了普通除法运算,而Affine解密需要计算
a在模26下的模逆元,不是直接做整数除法——直接除法要么得不出正确结果,要么触发除以0的异常。
具体修复步骤
第一步:更换合法的a密钥
先把加密用的a换成和26互质的数,比如3、5、7、9、11这类值。比如用a=3配合b=8加密"Hello, World!",之后用修复后的解密函数就能正常还原原始文本。
要是你非要用
a=4,建议直接放弃——因为它和26不互质,解密不存在唯一解,根本没法通过常规Affine解密拿回原始文本。
第二步:修复解密脚本的模逆元计算
正确的Affine解密公式是:x = a⁻¹*(y - b) mod 26
这里的a⁻¹是a在模26下的逆元,即找到一个整数,和a相乘后模26等于1。
以下是修复后的完整脚本逻辑:
实现模逆元计算函数
mod_inverse() { local a=$1 m=$2 local m0=$m local y=0 x=1 if [ $m -eq 1 ]; then echo 0 return fi while [ $a -gt 1 ]; do local q=$((a / m)) local t=$m m=$((a % m)) a=$t t=$y y=$((x - q * y)) x=$t done if [ $x -lt 0 ]; then x=$((x + m0)) fi echo $x }
修复后的affine_decrypt函数
affine_decrypt() { local ciphertext="$1" local a=$2 local b=$3 local m=26 # 先检查a和26是否互质,不合法直接报错 local gcd=$(gcd $a $m) if [ $gcd -ne 1 ]; then echo "错误:a=$a和26不互质,无法解密" return 1 fi local a_inv=$(mod_inverse $a $m) local plaintext="" for ((i=0; i<${#ciphertext}; i++)); do local char="${ciphertext:i:1}" # 处理大写字母 if [[ $char =~ [A-Z] ]]; then local y=$(( $(printf "%d" "'$char") - 65 )) local x=$(( (a_inv * (y - b)) % m )) # 保证结果为非负数 if [ $x -lt 0 ]; then x=$((x + m)) fi plaintext+=$(printf "\\$(printf "%03o" $((x + 65)))") # 处理小写字母(如需支持) elif [[ $char =~ [a-z] ]]; then local y=$(( $(printf "%d" "'$char") - 97 )) local x=$(( (a_inv * (y - b)) % m )) if [ $x -lt 0 ]; then x=$((x + m)) fi plaintext+=$(printf "\\$(printf "%03o" $((x + 97)))") # 非字母字符直接保留 else plaintext+="$char" fi done echo "$plaintext" } # 辅助函数:计算最大公约数 gcd() { local a=$1 b=$2 while [ $b -ne 0 ]; do local temp=$b b=$((a % b)) a=$temp done echo $a }
第三步:验证修复效果
用合法密钥加密后再解密测试:
# 假设你的affine_encrypt函数正常工作 encrypted=$(affine_encrypt "Hello, World!" 3 8) # 用修复后的函数解密 decrypted=$(affine_decrypt "$encrypted" 3 8) echo $decrypted # 应输出:Hello, World!
补充说明
- 脚本里加入了
gcd检查,能提前拦截不合法的a值,避免后续出现奇怪的计算错误。 - 若坚持使用
a=4,加密后的每个密文字母对应两个原始字母,解密无法得到唯一的原始文本,这种情况密钥本身不符合Affine密码的规则,必须更换。
内容的提问来源于stack exchange,提问作者uday kiran reddy
相关产品推荐
相关产品推荐

