Skip to content

Instantly share code, notes, and snippets.

@obrassard
Last active December 22, 2020 04:14
Show Gist options
  • Save obrassard/7aca7a90077be0ff90e0d44ee0f5d785 to your computer and use it in GitHub Desktop.
Save obrassard/7aca7a90077be0ff90e0d44ee0f5d785 to your computer and use it in GitHub Desktop.
Kotlin implementation of a Caesar cypher decoder utility (See https://en.wikipedia.org/wiki/Caesar_cipher)
import kotlin.collections.HashMap
fun main() {
with(CaesarCypherDecoder()) {
val message = decode("QEB NRFZH YOLTK CLU GRJMP LSBO QEB IXWV ALD", 'K', 'H')
println("Decoded message : $message")
bruteForce("CZGGJ RJMGY DI V NZXMZODQZ HVIIZM")
}
}
/**
* Caesar cypher decoder.
* See https://en.wikipedia.org/wiki/Caesar_cipher
*/
class CaesarCypherDecoder {
private var alphabet: List<Char> = ArrayList<Char>().apply {
for (i in 0..25) this.add('A'+i)
}
fun decode(cypher: String, from: Char, to:Char): String {
val shift = from.toUpperCase() - to.toUpperCase()
return decode(cypher, shiftAlphabet(shift))
}
fun decode(cypher: String, shift: Int) = decode(cypher, shiftAlphabet(shift))
fun bruteForce(cypher: String): Map<Int, String> {
val candidates : Map<Int, String> = HashMap<Int, String>().apply {
for (i in 1..25) {
put(i, decode(cypher, i))
}
}
println(candidates)
return candidates
}
private fun decode(cypher: String, charMap:Map<Char,Char>): String {
val sanitizedMessage = cypher.toUpperCase()
if (sanitizedMessage.any { !alphabet.contains(it) && it != ' ' })
throw IllegalArgumentException("'$cypher' contains invalid characters")
val builder = StringBuilder()
for (c in sanitizedMessage) {
builder.append(charMap[c])
}
return builder.toString()
}
private fun shiftAlphabet(shift: Int): Map<Char, Char> {
val map: MutableMap<Char,Char> = hashMapOf(' ' to ' ')
for (c in alphabet) {
val newpos = Math.floorMod((alphabet.indexOf(c) + shift), alphabet.size)
map[c] = alphabet[newpos]
}
return map
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment