Playfair cipher: Difference between revisions

→‎{{header|Ruby}}: Add implementation.
m (→‎{{header|Raku}}: removed obsolete 'anon')
(→‎{{header|Ruby}}: Add implementation.)
Line 2,498:
════════════════Playfair encryption──► decryption──► encryption worked.
</pre>
 
=={{header|Ruby}}==
Printing the cipher in pairs just advertises the mechanism of encoding; I've gone with the traditional grouping into sequences of five letters instead.
 
<lang ruby>class Playfair
Size = 5
def initialize(key, missing)
@missing = missing.upcase
alphabet = ('A'..'Z').to_a.join.upcase.delete(@missing).split''
extended = key.upcase.gsub(/[^A-Z]/,'').split('') + alphabet
grid = extended.uniq[0...Size*Size].each_slice(Size).to_a
coords = {}
grid.each_with_index do |row, i|
row.each_with_index do |letter, j|
coords[letter] = [i,j]
end
end
@encode = {}
alphabet.product(alphabet).reject { |a,b| a==b }.each do |a, b|
i1, j1 = coords[a]
i2, j2 = coords[b]
if i1 == i2 then
j1 = (j1 + 1) % Size
j2 = (j2 + 1) % Size
elsif j1 == j2 then
i1 = (i1 + 1) % Size
i2 = (i2 + 1) % Size
else
j1, j2 = j2, j1
end
@encode["#{a}#{b}"] = "#{grid[i1][j1]}#{grid[i2][j2]}"
@decode = @encode.invert
end
end
 
def encode(plaintext)
plain = plaintext.upcase.gsub(/[^A-Z]/,'')
if @missing == 'J' then
plain = plain.gsub(/J/, 'I')
else
plain = plain.gsub(@missing, 'X')
end
plain = plain.gsub(/(.)\1/, '\1X\1')
if plain.length % 2 == 1 then
plain += 'X'
end
return plain.upcase.split('').each_slice(2).map do |pair|
@encode[pair.join]
end.join.split('').each_slice(5).map{|s|s.join}.join(' ')
end
 
def decode(ciphertext)
cipher = ciphertext.upcase.gsub(/[^A-Z]/,'')
return cipher.upcase.split('').each_slice(2).map do |pair|
@decode[pair.join]
end.join.split('').each_slice(5).map{|s|s.join}.join(' ')
end
end</lang>
 
{{Out}}
<pre>irb(main):001:0> cipher = (p=Playfair.new 'Playfair example','J').encode('hide the gold in the tree stump')
=> "BMODZ BXDNA BEKUD MUIXM MOUVI F"
irb(main):002:0> p.decode(cipher)
=> "HIDET HEGOL DINTH ETREX ESTUM P"</pre>
 
=={{header|Sidef}}==
1,480

edits