当前位置:网站首页>Go 语言入门很简单:Go 实现凯撒密码
Go 语言入门很简单:Go 实现凯撒密码
2022-07-04 12:45:00 【51CTO】
在文本上使用凯撒密码来移动字符。调用 strings.Map 方法。
1 凯撒密码加密
凯撒密码(英语:Caesar cipher),或称凯撒加密、凯撒变换、变换加密,是一种最简单且最广为人知的加密技术。
凯撒密码是一种替换加密技术,明文中的所有字母都在字母表上向后(或向前)按照一个固定数目进行偏移后被替换成密文。例如,当偏移量是 3 的时候,所有的字母 A 将被替换成 D;B 变成E,以此类推。这个加密方法是以罗马共和时期凯撒的名字命名的,据称当年凯撒曾用此方法与其将军们进行联系。
明文字母表:ABCDEFGHIJKLMNOPQRSTUVWXYZ 密文字母表:DEFGHIJKLMNOPQRSTUVWXYZABC

设计思想
- 设置明文和移动步长(秘文)
- 将清晰的文本转换为小写,准备清晰的文本字节切片和密文切片
- 每个明文字符根据位移的步长旋转并存储在密文片中
- 返回密文

2 Go实现
凯撒密码一般以密码形式交付。比如这串代码“exxegoexsrgi”是密码。
通过移动字母,我们可以对消息进行编码。这阻止了随意的窥探。在 Go 中,我们可以使用 strings.Map 方法来实现这一点。
2.1 导入包
2.2 编写 caesar 方法
然后让我们来编写 caesarEn() 凯撒密码加密方法。这会接收一个字符串并返回一个修改过的字符串。
它会移动字符,然后将字符移动到有效范围。
// 凯撒密码加密
func
caesarEn(
strRaw
string,
step
byte)
string {
//1. 将文本转为小写
str_raw :
=
strings.
ToLower(
strRaw)
//2. 定义步长
step_move :
=
step
//3. 将字符串转换为明文字符切片
str_slice_src :
= []
byte(
str_raw)
fmt.
Println(
"Clear text character slice:",
str_slice_src)
//4. 创建一个密文字符切片
str_slice_dst :
=
str_slice_src
//5.循环处理文本切片
for
i :
=
0;
i
<
len(
str_slice_src);
i
++ {
//6.如果当前周期的明文特征在位移范围内,请直接添加位移步骤以保存密文字符切片
if
str_slice_src[
i]
<
123
-
step_move {
str_slice_dst[
i]
=
str_slice_src[
i]
+
step_move
}
else {
//7. 如果明文字符超出范围,则加上位移后的步长减去 26
str_slice_dst[
i]
=
str_slice_src[
i]
+
step_move
-
26
}
}
//8. 输出结果
fmt.
Println(
"The encryption result is:",
step_move,
str_slice_dst,
string(
str_slice_dst))
return
string(
str_slice_dst)
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
3 凯撒密码解密
思想:
- 设置密文和位移步骤
- 准备密文字符切片和明文字符切片
- 每个密文的字符根据位移步长旋转,并存储在明文切片中
- 返回明文

Go 凯撒解密代码:
//2. 凯撒密码解密
func
caesarDe(
strCipher
string,
step
byte)
string {
//1. 将文本转为小写
str_cipher :
=
strings.
ToLower(
strCipher)
//2. 替代步长
step_move :
=
step
//3. 将字符串转换为明文字符切片
str_slice_src :
= []
byte(
str_cipher)
fmt.
Println(
"Ciphertext character slice:",
str_slice_src)
//4. 创建一个密文字符切片
str_slice_dst :
=
str_slice_src
//5. 循环处理字符文本切片
for
i :
=
0;
i
<
len(
str_slice_src);
i
++ {
//6. 如果当前周期的明文特征在位移范围内,请直接添加位移步骤以保存密文字符切片
if
str_slice_src[
i]
>=
97
+
step_move {
str_slice_dst[
i]
=
str_slice_src[
i]
-
step_move
}
else {
//7. 如果明文字符超出范围,则加上 26 减去位移后的步长
str_slice_dst[
i]
=
str_slice_src[
i]
+
26
-
step_move
}
}
//8. Output results
fmt.
Println(
"The decryption result is:",
step_move,
str_slice_dst,
string(
str_slice_dst))
return
string(
str_slice_dst)
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
4 其他实现
package
main
import (
"errors"
"fmt"
"reflect"
"regexp"
)
var
TBL
= []
rune(
"abcdefghijklmnopqrstuvwxyz")
var
CLUES
= []
string{
"this",
"the",
"that"}
var (
ErrLength
=
errors.
New(
"invalid length")
ErrChar
=
errors.
New(
"invalid char")
ErrNoClue
=
errors.
New(
"no clue word")
ErrShift
=
errors.
New(
"invalid shift value")
)
func
Encrypt(
in
string,
sh
int) (
enc
string,
err
error) {
err
=
assert(
in)
if
sh
<
0 {
err
=
ErrShift
}
if
err
!=
nil {
return
}
enc
=
shift(
in,
sh)
return
}
func
Decrypt(
in
string) (
dec
string,
sh
int,
err
error) {
err
=
assert(
in)
if
err
!=
nil {
return
}
var
hit
bool
=
false
subin :
=
subStr(
in)
for
i :
=
0;
i
<
len(
CLUES);
i
++ {
subclue :
=
subStr(
CLUES[
i])
for
j :
=
0;
j
<
len(
subin)
-
len(
subclue)
+
1;
j
++ {
if
reflect.
DeepEqual(
subin[
j:
j
+
1],
subclue[
0:
len(
subclue)
-
1]) {
sh
=
subtract([]
rune(
in)[
j], []
rune(
CLUES[
i])[
0])
hit
=
true
break
}
}
}
if
!
hit {
err
=
ErrNoClue
return
}
dec
=
shift(
in,
-
sh)
return
}
func
assert(
in
string) (
err
error) {
if
regexp.
MustCompile(
`[^a-z\. \r\n]`).
MatchString(
in) {
err
=
ErrChar
}
else
if
len(
in)
>
80 {
err
=
ErrLength
}
return
}
func
shift(
in
string,
sh
int) (
out
string) {
for
_,
v :
=
range
in {
if
v
==
'.'
||
v
==
' '
||
v
==
'\r'
||
v
==
'\n' {
out
+=
string(
v)
continue
}
i :
=
indexOf(
TBL,
v)
len :
=
len(
TBL)
var
ii
int
= (
i
+
sh)
%
len
if
ii
<
0 {
ii
+=
len
}
if
ii
>
len {
ii
-=
len
}
out
+=
string(
TBL[
ii])
}
return
}
func
subtract(
left
rune,
right
rune) (
out
int) {
l :
=
indexOf(
TBL,
left)
r :
=
indexOf(
TBL,
right)
out
=
l
-
r
if
out
<
0 {
out
+=
len(
TBL)
}
return
}
func
subStr(
in
string) []
int {
subin :
=
make([]
int,
0,
79)
for
i :
=
range
in {
if
i
>
len(
in)
-
2 {
break
}
subin
=
append(
subin,
subtract([]
rune(
in)[
i], []
rune(
in)[
i
+
1]))
}
// return
return
subin
}
func
indexOf(
target []
rune,
searchChar
rune)
int {
for
i,
v :
=
range
target {
if
v
==
searchChar {
return
i
}
}
return
-
1
}
func
main() {
in :
=
"xlmw mw xli tmgxyvi xlex m xsso mr xli xvmt."
fmt.
Printf(
"in : '%s'\n",
in)
out,
sh,
err :
=
Decrypt(
in)
fmt.
Printf(
"out: '%s'\n",
out)
fmt.
Printf(
"sh : %d\n",
sh)
fmt.
Printf(
"err: %v\n",
err)
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
- 82.
- 83.
- 84.
- 85.
- 86.
- 87.
- 88.
- 89.
- 90.
- 91.
- 92.
- 93.
- 94.
- 95.
- 96.
- 97.
- 98.
- 99.
- 100.
- 101.
- 102.
- 103.
- 104.
- 105.
- 106.
- 107.
- 108.
- 109.
- 110.
- 111.
- 112.
- 113.
- 114.
- 115.
- 116.
- 117.
- 118.
- 119.
- 120.
- 121.
- 122.
- 123.
- 124.
- 125.
- 126.
- 127.
- 128.
- 129.
- 130.
- 131.
- 132.
- 133.
- 134.
- 135.
- 136.
- 137.
- 138.
- 139.
- 140.
- 141.
- 142.
- 143.
- 144.
- 145.
- 146.
- 147.
- 148.
- 149.
- 150.
- 151.
- 152.
- 153.
5 测试
package
main
import (
"fmt"
"strings"
)
func
caesar(
r
rune,
shift
int)
rune {
// Shift character by specified number of places.
// ... If beyond range, shift backward or forward.
s :
=
int(
r)
+
shift
if
s
>
'z' {
return
rune(
s
-
26)
}
else
if
s
<
'a' {
return
rune(
s
+
26)
}
return
rune(
s)
}
func
main() {
value :
=
"test"
fmt.
Println(
value)
// Test the caesar method in a func argument to strings.Map.
value2 :
=
strings.
Map(
func(
r
rune)
rune {
return
caesar(
r,
18)
},
value)
value3 :
=
strings.
Map(
func(
r
rune)
rune {
return
caesar(
r,
-
18)
},
value2)
fmt.
Println(
value2,
value3)
value4 :
=
strings.
Map(
func(
r
rune)
rune {
return
caesar(
r,
1)
},
value)
value5 :
=
strings.
Map(
func(
r
rune)
rune {
return
caesar(
r,
-
1)
},
value4)
fmt.
Println(
value4,
value5)
value
=
"exxegoexsrgi"
result :
=
strings.
Map(
func(
r
rune)
rune {
return
caesar(
r,
-
4)
},
value)
fmt.
Println(
value,
result)
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
运行该程序:
6 总结
本文简单介绍了一个有意思的密码学中的凯撒密码,该算法是一种替换加密技术,并在 Go 代码中实现了该算法的加密和解密过程。
边栏推荐
猜你喜欢

Meituan Ali's Application Practice on multimodal recall

"Pre training weekly" issue 52: shielding visual pre training and goal-oriented dialogue

eclipse链接数据库中测试SQL语句删除出现SQL语句语法错误

2022kdd pre lecture | 11 first-class scholars take you to unlock excellent papers in advance

Commvault 和 Oracle 合作,在 Oracle 云上提供 Metallic数据管理即服务

实战:fabric 用户证书吊销操作流程

求解:在oracle中如何用一条语句用delete删除两个表中jack的信息

Dgraph: large scale dynamic graph dataset

【云原生 | Kubernetes篇】深入了解Ingress(十二)

面试官:Redis中哈希数据类型的内部实现方式是什么?
随机推荐
Excuse me, have you encountered this situation? CDC 1.4 cannot use timestamp when connecting to MySQL 5.7
比量子化学方法快六个数量级,一种基于绝热状态的绝热人工神经网络方法,可加速对偶氮苯衍生物及此类分子的模拟
The only core indicator of high-quality software architecture
【AI系统前沿动态第40期】Hinton:我的深度学习生涯与研究心法;Google辟谣放弃TensorFlow;封神框架正式开源
在 Apache 上配置 WebDAV 服务器
光环效应——谁说头上有光的就算英雄
阿里云有奖体验:用PolarDB-X搭建一个高可用系统
Efficient! Build FTP working environment with virtual users
C语言中学生成绩管理系统
Optional values and functions of the itemized contenttype parameter in the request header
C language dormitory management query software
A data person understands and deepens the domain model
AI painting minimalist tutorial
CVPR 2022 | TransFusion:用Transformer进行3D目标检测的激光雷达-相机融合
ViewBinding和DataBinding的理解和区别
.NET 使用 redis
聊聊支付流程的设计与实现逻辑
Deploy halo blog with pagoda
高质量软件架构的唯一核心指标
Commvault 和 Oracle 合作,在 Oracle 云上提供 Metallic数据管理即服务