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

如何基于现有Bash实现的Vigenère加密脚本完成解密功能?

Vigenère密码Bash脚本:从加密扩展到解密

看起来你已经搞定了Vigenère加密的Bash脚本,现在想复用现有代码实现解密功能对吧?其实核心逻辑只需要反向调整一下位移计算,再通过参数区分加密/解密模式就能搞定,不用重新写一套代码。

先把你提供的原脚本补全(看起来最后截断了,我补了合理的加密逻辑):

#!/usr/local/bin/bash
# vigenere.sh
# Vigenère Cipher Implementation (Encryption Only)
a="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
# Check for invalid arguments
[[ "${*/-d/}" != "" ]] && echo "Usage: $0 [-d]" && exit 1

# 补全的加密核心逻辑
read -p "Enter plaintext: " plaintext
read -p "Enter key: " key

plaintext=$(echo "$plaintext" | tr '[:lower:]' '[:upper:]')
key=$(echo "$key" | tr '[:lower:]' '[:upper:]' | tr -cd '[:upper:]')

key_len=${#key}
result=""

for (( i=0; i<${#plaintext}; i++ )); do
    char=${plaintext:$i:1}
    if [[ "$char" =~ [A-Z] ]]; then
        plain_pos=$(expr index "$a" "$char")
        key_char=${key:$((i % key_len)):1}
        key_pos=$(expr index "$a" "$key_char")
        cipher_pos=$(( (plain_pos + key_pos - 2) % 26 + 1 ))
        cipher_char=${a:$((cipher_pos - 1)):1}
        result+="$cipher_char"
    else
        result+="$char"
    fi
done

echo "Encrypted text: $result"

核心逻辑分析

加密的本质是:明文字母在字母表的位置 + 密钥对应字母的位置,模26后得到密文字母的位置(因为expr index返回的是从1开始的索引,所以要做-2的调整)。

解密的逻辑刚好相反:密文字母的位置 - 密钥对应字母的位置,模26后得到明文字母的位置,这里要注意处理负数的情况(比如密文字母位置比密钥位置小的时候)。

复用代码的改造方案

我把脚本改成支持-d参数切换解密模式,并且把核心转换逻辑抽成函数,避免重复代码:

#!/usr/local/bin/bash
# vigenere.sh
# Vigenère Cipher Implementation (Encryption + Decryption)
a="ABCDEFGHIJKLMNOPQRSTUVWXYZ"

# 显示用法提示
show_usage() {
    echo "Usage: $0 [-d]"
    echo "  Without -d: Encrypt plaintext"
    echo "  With -d: Decrypt ciphertext"
    exit 1
}

# 判断运行模式:加密/解密
mode="encrypt"
if [[ "$1" == "-d" ]]; then
    mode="decrypt"
    shift
fi
# 检查多余参数
[[ $# -ne 0 ]] && show_usage

# 核心字符转换函数:根据模式处理单个字符和密钥字符
transform_char() {
    local char=$1
    local key_char=$2
    local mode=$3

    local plain_pos=$(expr index "$a" "$char")
    local key_pos=$(expr index "$a" "$key_char")
    local result_pos

    if [[ "$mode" == "encrypt" ]]; then
        # 加密公式:(明文位置 + 密钥位置 - 2) mod 26 + 1
        result_pos=$(( (plain_pos + key_pos - 2) % 26 + 1 ))
    else
        # 解密公式:处理负数,确保结果在1-26之间
        result_pos=$(( (plain_pos - key_pos) % 26 ))
        result_pos=$(( result_pos < 0 ? result_pos + 26 : result_pos ))
        result_pos=$(( result_pos == 0 ? 26 : result_pos ))
    fi

    echo "${a:$((result_pos - 1)):1}"
}

# 获取用户输入
if [[ "$mode" == "encrypt" ]]; then
    read -p "Enter plaintext to encrypt: " input_text
else
    read -p "Enter ciphertext to decrypt: " input_text
fi
read -p "Enter key (letters only): " key

# 统一格式:转大写,密钥只保留字母
input_text=$(echo "$input_text" | tr '[:lower:]' '[:upper:]')
key=$(echo "$key" | tr '[:lower:]' '[:upper:]' | tr -cd '[:upper:]')

# 检查密钥合法性
if [[ -z "$key" ]]; then
    echo "Error: Key cannot be empty or non-alphabetic"
    exit 1
fi

key_len=${#key}
result=""

# 逐字符处理输入文本
for (( i=0; i<${#input_text}; i++ )); do
    char=${input_text:$i:1}
    if [[ "$char" =~ [A-Z] ]]; then
        key_char=${key:$((i % key_len)):1}
        transformed_char=$(transform_char "$char" "$key_char" "$mode")
        result+="$transformed_char"
    else
        # 非字母字符直接保留
        result+="$char"
    fi
done

# 输出结果
if [[ "$mode" == "encrypt" ]]; then
    echo "Encrypted result: $result"
else
    echo "Decrypted result: $result"
fi

关键改造点说明

  • 模式切换:通过-d参数设置解密模式,默认是加密模式,同时增加了参数合法性检查
  • 代码复用:把加密和解密的核心字符转换逻辑抽成transform_char函数,只在函数内部根据模式切换计算方式
  • 负数处理:解密时如果密文字母位置减密钥位置得到负数,先加26再取模,确保结果始终是1-26之间的有效索引
  • 鲁棒性提升:增加了密钥合法性检查,避免空密钥或非字母密钥的情况

使用方法

  • 加密:直接运行./vigenere.sh,输入明文和密钥即可
  • 解密:运行./vigenere.sh -d,输入密文和密钥即可

内容的提问来源于stack exchange,提问作者Neo1234

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:27:58