Skip to content

Latest commit

 

History

History
121 lines (116 loc) · 3.76 KB

2023-4-26.md

File metadata and controls

121 lines (116 loc) · 3.76 KB

使用Shell命令实现一种简单加密

简述实现方法

  • 首先对于多行输入的问题,采用read -r接受,同时为每行结尾添加换行符;内部处理时识别换行符而不进行处理;输出则通过echo -e识别换行符输出。
  • 交互式设计,用户传入n的值、模式选择、字符串,程序调用encryptdecrypt函数,实现转换。
  • 函数遍历字符串,判断是否是大写字母或小写字母,将其ASCII码处理为与A或a差值,加上或减去n,对26去模后再加上A或a的ASCII码恢复,保存对应字符,加入到函数返回的字符串中。对于减去n,还需要考虑减后小于零的i情况。
  • 完整代码如下:
#!/bin/bash

# 加密函数
encrypt() {
    plaintext=$1
    key=$2
    ciphertext=""
    flag=0
    for ((i = 0; i < ${#plaintext}; i++)); do
        ttest=${plaintext:i:2}
        if [[ $flag == 1 ]]; then
            flag=0
            continue
        fi
        if [[ $ttest == $"\n" ]]; then
            ciphertext+="\n"
            flag=1
            continue
        fi
        char=${plaintext:$i:1}
        ascii_val=$(printf "%d" "'$char")
        if [[ $ascii_val -ge 65 && $ascii_val -le 90 ]]; then
            shifted_ascii_val=$((($ascii_val - 65 + $key) % 26 + 65))
            shifted_char=$(printf "\\$(printf %o $shifted_ascii_val)")
            ciphertext+=$shifted_char
        elif [[ $ascii_val -ge 97 && $ascii_val -le 122 ]]; then
            shifted_ascii_val=$((($ascii_val - 97 + $key) % 26 + 97))
            shifted_char=$(printf "\\$(printf %o $shifted_ascii_val)")
            ciphertext+=$shifted_char
        else
            ciphertext+=$char
        fi
    done
    echo $ciphertext
}

# 解密函数
decrypt() {
    ciphertext=$1
    key=$2
    plaintext=""
    flag=0
    for ((i = 0; i < ${#ciphertext}; i++)); do
        ttest=${ciphertext:i:2}
        if [[ $flag == 1 ]]; then
            flag=0
            continue
        fi
        if [[ $ttest == $"\n" ]]; then
            plaintext+="\n"
            flag=1
            continue
        fi
        char=${ciphertext:$i:1}
        ascii_val=$(printf "%d" "'$char")
        if [[ $ascii_val -ge 65 && $ascii_val -le 90 ]]; then
            shifted_ascii_val=$(($ascii_val - 65 - $key))
            if (($shifted_ascii_val < 0)); then
                shifted_ascii_val=$((shifted_ascii_val + 26))
            fi
            shifted_ascii_val=$((shifted_ascii_val + 65))
            shifted_char=$(printf "\\$(printf %o $shifted_ascii_val)")
            plaintext+=$shifted_char
        elif [[ $ascii_val -ge 97 && $ascii_val -le 122 ]]; then
            shifted_ascii_val=$(($ascii_val - 97 - $key))
            if (($shifted_ascii_val < 0)); then
                shifted_ascii_val=$((shifted_ascii_val + 26))
            fi
            shifted_ascii_val=$((shifted_ascii_val + 97))
            shifted_char=$(printf "\\$(printf %o $shifted_ascii_val)")
            plaintext+=$shifted_char
        else
            plaintext+=$char
        fi
    done
    echo $plaintext
}

echo "请输入n的值:"
read key
echo "请选择操作类型:"
echo "1. 加密"
echo "2. 解密"
read op

if [ $op == 1 ]; then
    echo "输入明文:"
    text=""
    while IFS= read -r line; do
        if [[ "$line" == "EOF" ]]; then
            break
        fi
        text+="$line"
        text+="\n"
    done
    ciphertext=$(encrypt "$text" $key)
    echo -e "暗文: $ciphertext"
elif [ $op == 2 ]; then
    echo "输入暗文:"
    text=""
    while IFS= read -r line; do
        if [[ "$line" == "EOF" ]]; then
            break
        fi
        text+="$line"
        text+="\n"
    done
    decrypted_plaintext=$(decrypt "$text" $key)
    echo -e "明文: $decrypted_plaintext"
else
    echo "无效的操作类型"
fi