summaryrefslogtreecommitdiff
path: root/go/crypto-square/crypto_square.go
blob: afb94f7692fc96ba8f36183176d3b3e209dd32be (plain)
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
package cryptosquare

import (
	"math"
	"strings"
	"unicode"
)

const testVersion = 2

func normalize(s string) string {
	var r []rune
	for _, v := range s {
		if unicode.IsLetter(v) || unicode.IsNumber(v) {
			r = append(r, unicode.ToLower(v))
		}
	}
	return string(r)
}

func split(s string) []string {
	cols := int(math.Ceil(math.Sqrt(float64(len(s)))))
	rows := len(s) / cols
	if len(s)%cols != 0 {
		rows++
	}
	r := make([]string, rows)
	for i := range r {
		start := i * cols
		end := start + cols
		if end > len(s) {
			end = len(s)
		}
		r[i] = s[start:end]
	}
	return r
}

func transpose(s []string) []string {
	r := make([][]byte, len(s[0]))
	for j := 0; j < len(s); j++ {
		for i := 0; i < len(s[j]); i++ {
			r[i] = append(r[i], s[j][i])
		}
	}
	ret := make([]string, len(s[0]))
	for i := range ret {
		ret[i] = string(r[i])
	}
	return ret
}

func Encode(s string) string {
	if len(s) == 0 {
		return ""
	}
	return strings.Join(transpose(split(normalize(s))), " ")
}