September 2017 Update
This commit is contained in:
parent
bba7bfd280
commit
ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions
163
Task/The-ISAAC-Cipher/Kotlin/the-isaac-cipher.kotlin
Normal file
163
Task/The-ISAAC-Cipher/Kotlin/the-isaac-cipher.kotlin
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
// version 1.1.3
|
||||
|
||||
/* external results */
|
||||
val randrsl = IntArray(256)
|
||||
var randcnt = 0
|
||||
|
||||
/* internal state */
|
||||
val mm = IntArray(256)
|
||||
var aa = 0
|
||||
var bb = 0
|
||||
var cc = 0
|
||||
|
||||
const val GOLDEN_RATIO = 0x9e3779b9.toInt()
|
||||
|
||||
fun isaac() {
|
||||
cc++ // cc just gets incremented once per 256 results
|
||||
bb += cc // then combined with bb
|
||||
for (i in 0..255) {
|
||||
val x = mm[i]
|
||||
when (i % 4) {
|
||||
0 -> aa = aa xor (aa shl 13)
|
||||
1 -> aa = aa xor (aa ushr 6)
|
||||
2 -> aa = aa xor (aa shl 2)
|
||||
3 -> aa = aa xor (aa ushr 16)
|
||||
}
|
||||
aa += mm[(i + 128) % 256]
|
||||
val y = mm[(x ushr 2) % 256] + aa + bb
|
||||
mm[i] = y
|
||||
bb = mm[(y ushr 10) % 256] + x
|
||||
randrsl[i] = bb
|
||||
}
|
||||
randcnt = 0
|
||||
}
|
||||
|
||||
/* if (flag == true), then use the contents of randrsl to initialize mm. */
|
||||
fun mix(n: IntArray) {
|
||||
n[0] = n[0] xor (n[1] shl 11); n[3] += n[0]; n[1] += n[2]
|
||||
n[1] = n[1] xor (n[2] ushr 2); n[4] += n[1]; n[2] += n[3]
|
||||
n[2] = n[2] xor (n[3] shl 8); n[5] += n[2]; n[3] += n[4]
|
||||
n[3] = n[3] xor (n[4] ushr 16); n[6] += n[3]; n[4] += n[5]
|
||||
n[4] = n[4] xor (n[5] shl 10); n[7] += n[4]; n[5] += n[6]
|
||||
n[5] = n[5] xor (n[6] ushr 4); n[0] += n[5]; n[6] += n[7]
|
||||
n[6] = n[6] xor (n[7] shl 8); n[1] += n[6]; n[7] += n[0]
|
||||
n[7] = n[7] xor (n[0] ushr 9); n[2] += n[7]; n[0] += n[1]
|
||||
}
|
||||
|
||||
fun randinit(flag: Boolean) {
|
||||
aa = 0
|
||||
bb = 0
|
||||
cc = 0
|
||||
val n = IntArray(8) { GOLDEN_RATIO }
|
||||
for (i in 0..3) mix(n) // scramble the array
|
||||
|
||||
for (i in 0..255 step 8) { // fill in mm with messy stuff
|
||||
if (flag) { // use all the information in the seed
|
||||
for (j in 0..7) n[j] += randrsl[i + j]
|
||||
}
|
||||
mix(n)
|
||||
for (j in 0..7) mm[i + j] = n[j]
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
/* do a second pass to make all of the seed affect all of mm */
|
||||
for (i in 0..255 step 8) {
|
||||
for (j in 0..7) n[j] += mm[i + j]
|
||||
mix(n)
|
||||
for (j in 0..7) mm[i + j] = n[j]
|
||||
}
|
||||
}
|
||||
|
||||
isaac() // fill in the first set of results
|
||||
randcnt = 0 // prepare to use the first set of results
|
||||
}
|
||||
|
||||
/* As Kotlin doesn't (yet) support unsigned types, we need to use
|
||||
Long here to get a random value in the range of a UInt */
|
||||
fun iRandom(): Long {
|
||||
val r = randrsl[randcnt++]
|
||||
if (randcnt > 255) {
|
||||
isaac()
|
||||
randcnt = 0
|
||||
}
|
||||
return r.toLong() and 0xFFFFFFFFL
|
||||
}
|
||||
|
||||
/* Get a random character (as Int) in printable ASCII range */
|
||||
fun iRandA() = (iRandom() % 95 + 32).toInt()
|
||||
|
||||
/* Seed ISAAC with a string */
|
||||
fun iSeed(seed: String, flag: Boolean) {
|
||||
for (i in 0..255) mm[i] = 0
|
||||
val m = seed.length
|
||||
for (i in 0..255) {
|
||||
/* in case seed has less than 256 elements */
|
||||
randrsl[i] = if (i >= m) 0 else seed[i].toInt()
|
||||
}
|
||||
/* initialize ISAAC with seed */
|
||||
randinit(flag)
|
||||
}
|
||||
|
||||
/* XOR cipher on random stream. Output: ASCII string */
|
||||
fun vernam(msg: String) : String {
|
||||
val len = msg.length
|
||||
val v = ByteArray(len)
|
||||
for (i in 0 until len) {
|
||||
v[i] = (iRandA() xor msg[i].toInt()).toByte()
|
||||
}
|
||||
return v.toString(charset("ASCII"))
|
||||
}
|
||||
|
||||
/* constants for Caesar */
|
||||
const val MOD = 95
|
||||
const val START = 32
|
||||
|
||||
/* cipher modes for Caesar */
|
||||
enum class CipherMode {
|
||||
ENCIPHER, DECIPHER, NONE
|
||||
}
|
||||
|
||||
/* Caesar-shift a printable character */
|
||||
fun caesar(m: CipherMode, ch: Int, shift: Int, modulo: Int, start: Int): Char {
|
||||
val sh = if (m == CipherMode.DECIPHER) -shift else shift
|
||||
var n = (ch - start) + sh
|
||||
n %= modulo
|
||||
if (n < 0) n += modulo
|
||||
return (start + n).toChar()
|
||||
}
|
||||
|
||||
/* Caesar-shift a string on a pseudo-random stream */
|
||||
fun caesarStr(m: CipherMode, msg: String, modulo: Int, start: Int): String {
|
||||
val sb = StringBuilder(msg.length)
|
||||
/* Caesar-shift message */
|
||||
for (c in msg) {
|
||||
sb.append(caesar(m, c.toInt(), iRandA(), modulo, start))
|
||||
}
|
||||
return sb.toString()
|
||||
}
|
||||
|
||||
fun String.toHexByteString() =
|
||||
this.map { "%02X".format(it.toInt()) }.joinToString("")
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val msg = "a Top Secret secret"
|
||||
val key = "this is my secret key"
|
||||
|
||||
// Vernam & Caesar ciphertext
|
||||
iSeed(key, true)
|
||||
val vctx = vernam(msg)
|
||||
val cctx = caesarStr(CipherMode.ENCIPHER, msg, MOD, START)
|
||||
|
||||
// Vernam & Caesar plaintext
|
||||
iSeed(key, true)
|
||||
val vptx = vernam(vctx)
|
||||
val cptx = caesarStr(CipherMode.DECIPHER, cctx, MOD, START)
|
||||
|
||||
// Program output
|
||||
println("Message : $msg")
|
||||
println("Key : $key")
|
||||
println("XOR : ${vctx.toHexByteString()}")
|
||||
println("XOR dcr : $vptx")
|
||||
println("MOD : ${cctx.toHexByteString()}")
|
||||
println("MOD dcr : $cptx")
|
||||
}
|
||||
|
|
@ -1,20 +1,20 @@
|
|||
require('Math::Random::ISAAC');
|
||||
require('Math::Random::ISAAC')
|
||||
|
||||
func xor_isaac(key, msg) {
|
||||
var rng = %s<Math::Random::ISAAC>.new(unpack('C*', key));
|
||||
var rng = %O<Math::Random::ISAAC>.new(unpack('C*', key))
|
||||
|
||||
msg.chars»ord»() \
|
||||
-> »^« 256.of{ rng.irand % 95 + 32 }.last(msg.len).reverse \
|
||||
-> «%« '%02X' -> join;
|
||||
msg.chars»ord()» \
|
||||
-> »^« 256.of{ rng.irand % 95 + 32 }.last(msg.len).flip \
|
||||
-> «%« '%02X' -> join
|
||||
}
|
||||
|
||||
var msg = 'a Top Secret secret';
|
||||
var key = 'this is my secret key';
|
||||
var msg = 'a Top Secret secret'
|
||||
var key = 'this is my secret key'
|
||||
|
||||
var enc = xor_isaac(key, msg);
|
||||
var dec = xor_isaac(key, pack('H*', enc));
|
||||
var enc = xor_isaac(key, msg)
|
||||
var dec = xor_isaac(key, pack('H*', enc))
|
||||
|
||||
say "Message: #{msg}";
|
||||
say "Key : #{key}";
|
||||
say "XOR : #{enc}";
|
||||
say "XOR dcr: #{pack('H*', dec)}";
|
||||
say "Message: #{msg}"
|
||||
say "Key : #{key}"
|
||||
say "XOR : #{enc}"
|
||||
say "XOR dcr: #{pack('H*', dec)}"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue