我打算创建一个Caesar Cypher,它接受一个参数并根据该参数移动代码但我的代码与大写和小写混淆。
所以,它的意思是:
$ echo "I came, I saw, I conquered." | ./caesar.sh
V pnzr, V fnj, V pbadhrerq.
但我明白了:
V pnzr, V FnJ, V pBADHERrq.
我的代码是:
#!/bin/sh
if [ -z "$@" ];then
rotation=13;
else
rotation=$((@ % 16));
fi
tr $(printf %${rotation}s | tr ' ' '.')\a-zA-Z a-zA-Z
我该如何解决这个问题?
答案 0 :(得分:1)
你正在整个双字母表中旋转,' a-zA-Z'所以' s'映射到' F':
abcdefghijklmnopqrstuvwxyzABCDEFGHIKLMNOPQRSTUVWXYZ
|------------^
您显然希望保留案例,因此我建议您应用两个单独的映射:首先,映射' a-z'到' n-za-m' (或者其他,适合您的输入参数)。然后在第二遍中,映射大写字母,A-Z' - > ' N-ZA-M'
答案 1 :(得分:0)
您的方案的基本改编是:
rotation=$((${1:-13} % 26))
padding=$(printf "%${rotation}s" "" | tr ' ' '\001')
tr "${padding}a-z" "a-za-z" |
tr "${padding}A-Z" "A-ZA-Z"
这使用parameter expansion和arithmetic来确定轮换。
它使用您的基本机制来设置填充,但使用 Control-A 而不是.
作为填充字符;你的文本中很少有Control-A。
实际旋转命令与大写分开处理小写。
使用文件script.sh
中包含的脚本,我得到了:
$ bash script.sh
I came, I saw, I conquered
Can you say SYZYGY after midnight?
V pnzr, V fnj, V pbadhrerq
Pna lbh fnl FLMLTL nsgre zvqavtug?
$ bash script.sh 3
I came, I saw, I conquered, and O, was it ever worthwhile!
Can you say SYZYGY after midnight? ABC...XYZ abc...xyz
L fdph, L vdz, L frqtxhuhg, dqg R, zdv lw hyhu zruwkzkloh!
Fdq brx vdb VBCBJB diwhu plgqljkw? DEF...ABC def...abc
$
管道意味着第一行输入未被推送到行尾的第二个tr
命令。