多表代替密码
简介
加密仅能对26个字母进行加密
将A~Z以0~25编号
最上面一行为明文,左侧一列为密钥。
加密过程很简单,就是给定密钥字母x和明文字母y,密文字母是位于x行和y列的那个字母。这样就决定了加密一条消息需要与消息一样长的密钥字符串,通常,密钥字符串是密钥词的重复。
公式
如果假设能被加密的字符有N个,如果把这N个字符建成一个环,那么加密过程就是模N的过程,即,C(i)=(K(i)+P(i))modN,其中K、C、P分别代表的是密钥空间、密文空间、消息(明文)空间。
举例
比如密钥词是deceptive,消息是“we are discovered save
yourself”,那么加密过程如下:
deceptivedeceptivedeceptive(密钥字符串)
wearediscoveredsaveyourself(消息)
ZICVTWQNGRZGVTWAVZHCQYGLMGJ(密文)
从Vigenere代换表中,以密钥字符串中的“d”为行,消息中的“w”为列的那个字母就是“Z”了
C(i) = (K(i)+P(i))modN
c(1) = (3+22) mod 26
c(1) = 25 = Z
package main
import "fmt"
func Sanitize(in string) string {
out := []rune{}
for _, v := range in {
if 65 <= v && v <= 90 { //A-Z
out = append(out, v)
} else if 97 <= v && v <= 122 { //a-z
out = append(out, v-32) //小写转为大写
}
}
return string(out)
}
func Quartets(in string) string {
out := make([]rune, 0, len(in))
for i, v := range in {
if i%4 == 0 && i != 0 {
out = append(out, rune(32))
}
out = append(out, v)
}
return string(out)
}
func EncodePair(a, b rune) rune {
return (((a - 'A') + (b - 'A')) % 26) + 'A' //(K(i)+P(i))modN
}
func DecodePair(a, b rune) rune {
return (((((a - 'A') - (b - 'A')) + 26) % 26) + 'A')
}
func Encipher(msg, key string) string {
smsg, skey := Sanitize(msg), Sanitize(key)
out := make([]rune, 0, len(msg))
for i, v := range smsg {
out = append(out, EncodePair(v, rune(skey[i%len(skey)]))) //rune(skey[i%len(skey)] 获取该值对应的密钥
}
return string(out)
}
func Decipher(msg, key string) string {
smsg, skey := Sanitize(msg), Sanitize(key)
out := make([]rune, 0, len(msg))
for i, v := range smsg {
out = append(out, DecodePair(v, rune(skey[i%len(skey)])))
}
return string(out)
}
func main(){
key := "Typewriter"
message := "Now is the time for all good men to come to the aid of their country"
encoded := Encipher(message, key)
decoded := Decipher(encoded, key)
fmt.Println(encoded,decoded)
}