Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
133
Task/Playfair-cipher/Kotlin/playfair-cipher.kotlin
Normal file
133
Task/Playfair-cipher/Kotlin/playfair-cipher.kotlin
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
// version 1.0.5-2
|
||||
|
||||
enum class PlayfairOption {
|
||||
NO_Q,
|
||||
I_EQUALS_J
|
||||
}
|
||||
|
||||
class Playfair(keyword: String, val pfo: PlayfairOption) {
|
||||
private val table: Array<CharArray> = Array(5, { CharArray(5) }) // 5 x 5 char array
|
||||
|
||||
init {
|
||||
// build table
|
||||
val used = BooleanArray(26) // all elements false
|
||||
if (pfo == PlayfairOption.NO_Q)
|
||||
used[16] = true // Q used
|
||||
else
|
||||
used[9] = true // J used
|
||||
val alphabet = keyword.toUpperCase() + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
var i = 0
|
||||
var j = 0
|
||||
var c: Char
|
||||
var d: Int
|
||||
for (k in 0 until alphabet.length) {
|
||||
c = alphabet[k]
|
||||
if (c !in 'A'..'Z') continue
|
||||
d = c.toInt() - 65
|
||||
if (!used[d]) {
|
||||
table[i][j] = c
|
||||
used[d] = true
|
||||
if (++j == 5) {
|
||||
if (++i == 5) break // table has been filled
|
||||
j = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getCleanText(plainText: String): String {
|
||||
val plainText2 = plainText.toUpperCase() // ensure everything is upper case
|
||||
// get rid of any non-letters and insert X between duplicate letters
|
||||
var cleanText = ""
|
||||
var prevChar = '\u0000' // safe to assume null character won't be present in plainText
|
||||
var nextChar: Char
|
||||
for (i in 0 until plainText2.length) {
|
||||
nextChar = plainText2[i]
|
||||
// It appears that Q should be omitted altogether if NO_Q option is specified - we assume so anyway
|
||||
if (nextChar !in 'A'..'Z' || (nextChar == 'Q' && pfo == PlayfairOption.NO_Q)) continue
|
||||
// If I_EQUALS_J option specified, replace J with I
|
||||
if (nextChar == 'J' && pfo == PlayfairOption.I_EQUALS_J) nextChar = 'I'
|
||||
if (nextChar != prevChar)
|
||||
cleanText += nextChar
|
||||
else
|
||||
cleanText += "X" + nextChar
|
||||
prevChar = nextChar
|
||||
}
|
||||
val len = cleanText.length
|
||||
if (len % 2 == 1) { // dangling letter at end so add another letter to complete digram
|
||||
if (cleanText[len - 1] != 'X')
|
||||
cleanText += 'X'
|
||||
else
|
||||
cleanText += 'Z'
|
||||
}
|
||||
return cleanText
|
||||
}
|
||||
|
||||
private fun findChar(c: Char): Pair<Int, Int> {
|
||||
for (i in 0..4)
|
||||
for (j in 0..4)
|
||||
if (table[i][j] == c) return Pair(i, j)
|
||||
return Pair(-1, -1)
|
||||
}
|
||||
|
||||
fun encode(plainText: String): String {
|
||||
val cleanText = getCleanText(plainText)
|
||||
var cipherText = ""
|
||||
val length = cleanText.length
|
||||
for (i in 0 until length step 2) {
|
||||
val (row1, col1) = findChar(cleanText[i])
|
||||
val (row2, col2) = findChar(cleanText[i + 1])
|
||||
cipherText += when {
|
||||
row1 == row2 -> table[row1][(col1 + 1) % 5].toString() + table[row2][(col2 + 1) % 5]
|
||||
col1 == col2 -> table[(row1 + 1) % 5][col1].toString() + table[(row2 + 1) % 5][col2]
|
||||
else -> table[row1][col2].toString() + table[row2][col1]
|
||||
}
|
||||
if (i < length - 1) cipherText += " "
|
||||
}
|
||||
return cipherText
|
||||
}
|
||||
|
||||
fun decode(cipherText: String): String {
|
||||
var decodedText = ""
|
||||
val length = cipherText.length
|
||||
for (i in 0 until length step 3) { // cipherText will include spaces so we need to skip them
|
||||
val (row1, col1) = findChar(cipherText[i])
|
||||
val (row2, col2) = findChar(cipherText[i + 1])
|
||||
decodedText += when {
|
||||
row1 == row2 -> table[row1][if (col1 > 0) col1 - 1 else 4].toString() + table[row2][if (col2 > 0) col2 - 1 else 4]
|
||||
col1 == col2 -> table[if (row1 > 0) row1- 1 else 4][col1].toString() + table[if (row2 > 0) row2 - 1 else 4][col2]
|
||||
else -> table[row1][col2].toString() + table[row2][col1]
|
||||
}
|
||||
if (i < length - 1) decodedText += " "
|
||||
}
|
||||
return decodedText
|
||||
}
|
||||
|
||||
fun printTable() {
|
||||
println("The table to be used is :\n")
|
||||
for (i in 0..4) {
|
||||
for (j in 0..4) print(table[i][j] + " ")
|
||||
println()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
print("Enter Playfair keyword : ")
|
||||
val keyword: String = readLine()!!
|
||||
var ignoreQ: String
|
||||
do {
|
||||
print("Ignore Q when buiding table y/n : ")
|
||||
ignoreQ = readLine()!!.toLowerCase()
|
||||
}
|
||||
while (ignoreQ != "y" && ignoreQ != "n")
|
||||
val pfo = if (ignoreQ == "y") PlayfairOption.NO_Q else PlayfairOption.I_EQUALS_J
|
||||
val playfair = Playfair(keyword, pfo)
|
||||
playfair.printTable()
|
||||
print("\nEnter plain text : ")
|
||||
val plainText: String = readLine()!!
|
||||
val encodedText = playfair.encode(plainText)
|
||||
println("\nEncoded text is : $encodedText")
|
||||
val decodedText = playfair.decode(encodedText)
|
||||
println("Decoded text is : $decodedText")
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue