Playfair cipher: Difference between revisions
Content added Content deleted
m (→{{header|Phix}}: sp) |
No edit summary |
||
Line 3,220: | Line 3,220: | ||
Encoded text is : BM OD ZB XD NA BE KU DM UI XM MO UV IF |
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> |
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}}== |
=={{header|Wren}}== |