Playfair cipher: Difference between revisions

no edit summary
No edit summary
Line 3,220:
Encoded text is : BM OD ZB XD NA BE KU DM UI XM MO UV IF
Decoded text is : HI DE TH EG OL DI NT HE TR EE ST UM PX</pre>
 
=={{header|Vlang}}==
{{trans|Go}}
<lang vlang>import os
import strings
type PlayfairOption = int
const (
no_q = 0
i_equals_j = 1
)
struct Playfair {
mut:
keyword string
pfo PlayfairOption
table [5][5]u8
}
fn (mut p Playfair) init() {
// Build table.
mut used := [26]bool{} // all elements false
if p.pfo == no_q {
used[16] = true // Q used
} else {
used[9] = true // J used
}
alphabet := p.keyword.to_upper() + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
for i, j, k := 0, 0, 0; k < alphabet.len; k++ {
c := alphabet[k]
if c < 'A'[0] || c > 'Z'[0] {
continue
}
d := int(c - 65)
if !used[d] {
p.table[i][j] = c
used[d] = true
j++
if j == 5 {
i++
if i == 5 {
break // table has been filled
}
j = 0
}
}
}
}
fn (p Playfair) get_clean_text(pt string) string {
// Ensure everything is upper case.
plain_text := pt.to_upper()
// Get rid of any non-letters and insert X between duplicate letters.
mut clean_text := strings.new_builder(128)
// Safe to assume null u8 won't be present in plain_text.
mut prev_byte := `\000`
for i in 0..plain_text.len {
mut next_byte := plain_text[i]
// It appears that Q should be omitted altogether if NO_Q option is specified;
// we assume so anyway.
if next_byte < 'A'[0] || next_byte > 'Z'[0] || (next_byte == 'Q'[0] && p.pfo == no_q) {
continue
}
// If i_equals_j option specified, replace J with I.
if next_byte == 'J'[0] && p.pfo == i_equals_j {
next_byte = 'I'[0]
}
if next_byte != prev_byte {
clean_text.write_u8(next_byte)
} else {
clean_text.write_u8('X'[0])
clean_text.write_u8(next_byte)
}
prev_byte = next_byte
}
l := clean_text.len
if l%2 == 1 {
// Dangling letter at end so add another letter to complete digram.
if clean_text.str()[l-1] != 'X'[0] {
clean_text.write_u8('X'[0])
} else {
clean_text.write_u8('Z'[0])
}
}
return clean_text.str()
}
fn (p Playfair) find_byte(c u8) (int, int) {
for i in 0..5 {
for j in 0..5 {
if p.table[i][j] == c {
return i, j
}
}
}
return -1, -1
}
fn (p Playfair) encode(plain_text string) string {
clean_text := p.get_clean_text(plain_text)
mut cipher_text := strings.new_builder(128)
l := clean_text.len
for i := 0; i < l; i += 2 {
row1, col1 := p.find_byte(clean_text[i])
row2, col2 := p.find_byte(clean_text[i+1])
if row1 == row2{
cipher_text.write_u8(p.table[row1][(col1+1)%5])
cipher_text.write_u8(p.table[row2][(col2+1)%5])
} else if col1 == col2{
cipher_text.write_u8(p.table[(row1+1)%5][col1])
cipher_text.write_u8(p.table[(row2+1)%5][col2])
} else {
cipher_text.write_u8(p.table[row1][col2])
cipher_text.write_u8(p.table[row2][col1])
}
if i < l-1 {
cipher_text.write_u8(' '[0])
}
}
return cipher_text.str()
}
fn (p Playfair) decode(cipher_text string) string {
mut decoded_text := strings.new_builder(128)
l := cipher_text.len
// cipher_text will include spaces so we need to skip them.
for i := 0; i < l; i += 3 {
row1, col1 := p.find_byte(cipher_text[i])
row2, col2 := p.find_byte(cipher_text[i+1])
if row1 == row2 {
mut temp := 4
if col1 > 0 {
temp = col1 - 1
}
decoded_text.write_u8(p.table[row1][temp])
temp = 4
if col2 > 0 {
temp = col2 - 1
}
decoded_text.write_u8(p.table[row2][temp])
} else if col1 == col2 {
mut temp := 4
if row1 > 0 {
temp = row1 - 1
}
decoded_text.write_u8(p.table[temp][col1])
temp = 4
if row2 > 0 {
temp = row2 - 1
}
decoded_text.write_u8(p.table[temp][col2])
} else {
decoded_text.write_u8(p.table[row1][col2])
decoded_text.write_u8(p.table[row2][col1])
}
if i < l-1 {
decoded_text.write_u8(' '[0])
}
}
return decoded_text.str()
}
fn (p Playfair) print_table() {
println("The table to be used is :\n")
for i in 0..5 {
for j in 0..5 {
print("${p.table[i][j].ascii_str()} ")
}
println('')
}
}
fn main() {
keyword := os.input("Enter Playfair keyword : ")
mut ignore_q := ''
for ignore_q != "y" && ignore_q != "n" {
ignore_q = os.input("Ignore Q when building table y/n : ").to_lower()
}
mut pfo := no_q
if ignore_q == "n" {
pfo = i_equals_j
}
mut table := [5][5]u8{}
mut pf := Playfair{keyword, pfo, table}
pf.init()
pf.print_table()
plain_text := os.input("\nEnter plain text : ")
encoded_text := pf.encode(plain_text)
println("\nEncoded text is : $encoded_text")
decoded_text := pf.decode(encoded_text)
println("Deccoded text is : $decoded_text")
}</lang>
 
{{out}}
Sample run:
<pre>
Enter Playfair keyword : Playfair example
Ignore Q when building table y/n : n
The table to be used is :
 
P L A Y F
I R E X M
B C D G H
K N O Q S
T U V W Z
 
Enter plain text : Hide the gold...in the TREESTUMP!!!!
 
Encoded text is : BM OD ZB XD NA BE KU DM UI XM MO UV IF
Deccoded text is : HI DE TH EG OL DI NT HE TR EX ES TU MP
</pre>
 
=={{header|Wren}}==
338

edits