4 Star 25 Fork 17

编程语言算法集 / Go

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
polybius.go 2.85 KB
一键复制 编辑 原始数据 按行查看 历史
// Package polybius is encrypting method with polybius square
// ref: https://en.wikipedia.org/wiki/Polybius_square#Hybrid_Polybius_Playfair_Cipher
package polybius
import (
"fmt"
"math"
"strings"
)
// Polybius is struct having size, characters, and key
type Polybius struct {
size int
characters string
key string
}
// NewPolybius returns a pointer to object of Polybius.
// If the size of "chars" is longer than "size",
// "chars" are truncated to "size".
func NewPolybius(key string, size int, chars string) (*Polybius, error) {
if size < 0 {
return nil, fmt.Errorf("provided size %d cannot be negative", size)
}
key = strings.ToUpper(key)
if size > len(chars) {
return nil, fmt.Errorf("provided size %d is too small to use to slice string %q of len %d", size, chars, len(chars))
}
for _, r := range chars {
if (r < 'a' || r > 'z') && (r < 'A' || r > 'Z') {
return nil, fmt.Errorf("provided string %q should only contain latin characters", chars)
}
}
chars = strings.ToUpper(chars)[:size]
for i, r := range chars {
if strings.ContainsRune(chars[i+1:], r) {
return nil, fmt.Errorf("%q contains same character %q", chars[i+1:], r)
}
}
if len(key) != size*size {
return nil, fmt.Errorf("len(key): %d must be as long as size squared: %d", len(key), size*size)
}
return &Polybius{size, chars, key}, nil
}
// Encrypt encrypts with polybius encryption
func (p *Polybius) Encrypt(text string) (string, error) {
encryptedText := ""
for _, char := range strings.ToUpper(text) {
encryptedChar, err := p.encipher(char)
if err != nil {
return "", fmt.Errorf("failed encipher: %w", err)
}
encryptedText += encryptedChar
}
return encryptedText, nil
}
// Decrypt decrypts with polybius encryption
func (p *Polybius) Decrypt(text string) (string, error) {
chars := []rune(strings.ToUpper(text))
decryptedText := ""
for i := 0; i < len(chars); i += 2 {
decryptedChar, err := p.decipher(chars[i:int(math.Min(float64(i+2), float64(len(chars))))])
if err != nil {
return "", fmt.Errorf("failed decipher: %w", err)
}
decryptedText += decryptedChar
}
return decryptedText, nil
}
func (p *Polybius) encipher(char rune) (string, error) {
index := strings.IndexRune(p.key, char)
if index < 0 {
return "", fmt.Errorf("%q does not exist in keys", char)
}
row := index / p.size
col := index % p.size
chars := []rune(p.characters)
return string([]rune{chars[row], chars[col]}), nil
}
func (p *Polybius) decipher(chars []rune) (string, error) {
if len(chars) != 2 {
return "", fmt.Errorf("the size of \"chars\" must be even")
}
row := strings.IndexRune(p.characters, chars[0])
if row < 0 {
return "", fmt.Errorf("%c does not exist in characters", chars[0])
}
col := strings.IndexRune(p.characters, chars[1])
if col < 0 {
return "", fmt.Errorf("%c does not exist in characters", chars[1])
}
return string(p.key[row*p.size+col]), nil
}
Go
1
https://gitee.com/TheAlgorithms/Go.git
git@gitee.com:TheAlgorithms/Go.git
TheAlgorithms
Go
Go
master

搜索帮助