You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复Bash中仿射解密无法还原原文的问题?

修复Bash版Affine解密脚本的方案

问题出在哪

  1. 密钥a不符合规则:Affine密码要求密钥a必须和字母表长度m=26互质(两者最大公约数为1),你用的a=4和26的最大公约数是2,不满足条件。这会导致加密不是一一映射关系,解密根本无法得到唯一的原始文本,甚至直接触发计算错误。
  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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 05:13:10