The ISAAC cipher: Difference between revisions

m
(→‎{{header|Pascal}}: [0 .. 255] instead of [0..256]; unnecessary variables removed)
m (→‎{{header|Wren}}: Minor tidy)
 
(22 intermediate revisions by 12 users not shown)
Line 1:
{{draft task|Encryption}}
ISAAC is a cryptographically secure pseudo-random number generator (CSPRNG) and stream cipher. It was developed by Bob Jenkins from 1993 (http://burtleburtle.net/bob/rand/isaac.html) and placed in the Public Domain. ISAAC is fast - especially when optimised - and portable to most architectures in nearly all programming and scripting languages.
It is also simple and succinct, using as it does just two 256-word arrays for its state.
Line 59:
But building a strong and simple ISAAC-based stream cipher - replacing the irreparably broken RC4 - is our goal here: ISAAC's intended purpose.
<br><br>
 
=={{header|BASIC}}==
==={{header|FreeBASIC}}===
{{trans|C}}
<syntaxhighlight lang="freebasic">' version 03-11-2016
' compile with: fbc -s console
 
Dim Shared As UInteger<32> randrsl(256), randcnt
Static Shared As UInteger<32> mm(256)
Static Shared As UInteger<32> aa, bb ,cc
 
Sub ISAAC()
Dim As UInteger<32> i, x, y
cc = cc + 1
bb = bb + cc
For i = 0 To 256 -1
x = mm(i)
Select Case (i Mod 4)
Case 0 : aa = aa Xor (aa Shl 13)
Case 1 : aa = aa Xor (aa Shr 6)
Case 2 : aa = aa Xor (aa Shl 2)
Case 3 : aa = aa Xor (aa Shr 16)
End Select
aa = mm((i+128) Mod 256) + aa
y = mm((x Shr 2) Mod 256) + aa + bb : mm(i) = y
bb = mm((y Shr 10) Mod 256) + x : randrsl(i) = bb
Next
randcnt = 0
End Sub
 
#Macro mix(a, b, c, d, e, f, g, h)
a Xor= b Shl 11 : d += a : b += c
b Xor= c Shr 2 : e += b : c += d
c Xor= d Shl 8 : f += c : d += e
d Xor= e Shr 16 : g += d : e += f
e Xor= f Shl 10 : h += e : f += g
f Xor= g Shr 4 : a += f : g += h
g Xor= h Shl 8 : b += g : h += a
h Xor= a Shr 9 : c += h : a += b
#EndMacro
 
Sub randinit(flag As Long)
Dim As Long i
Dim As UInteger<32> a = &H9e3779b9 '/* the golden ratio *
Dim As UInteger<32> b = &H9e3779b9
Dim As UInteger<32> c = &H9e3779b9
Dim As UInteger<32> d = &H9e3779b9
Dim As UInteger<32> e = &H9e3779b9
Dim As UInteger<32> f = &H9e3779b9
Dim As UInteger<32> g = &H9e3779b9
Dim As UInteger<32> h = &H9e3779b9
aa = 0 : bb = 0 : cc = 0
For i = 0 To 3
mix(a, b, c, d, e, f, g, h)
Next
For i = 0 To 255 Step 8
If flag = 1 Then
a += randrsl(i ) : b += randrsl(i +1)
c += randrsl(i +2) : d += randrsl(i +3)
e += randrsl(i +4) : f += randrsl(i +5)
g += randrsl(i +6) : h += randrsl(i +7)
mix(a, b, c, d, e, f, g, h)
mm(i ) = a : mm(i +1) = b : mm(i +2) = c : mm(i +3) = d
mm(i +4) = e : mm(i +5) = f : mm(i +6) = g : mm(i +7) = h
End If
Next
If flag = 1 Then
For i = 0 To 255 Step 8
a += mm(i ) : b += mm(i +1)
c += mm(i +2) : d += mm(i +3)
e += mm(i +4) : f += mm(i +5)
g += mm(i +6) : h += mm(i +7)
mix(a, b, c, d, e, f, g, h)
mm(i )= a : mm(i +1) = b : mm(i +2) = c : mm(i +3) = d
mm(i +4)= e : mm(i +5) = f : mm(i +6) = g : mm(i +7) = h
Next
End If
ISAAC()
randcnt = 0
End Sub
 
' // Get a random 32-bit value 0..MAXINT
Function iRandom() As UInteger<32>
Dim As UInteger<32> r = randrsl(randcnt)
randcnt += 1
If randcnt > 255 Then
ISAAC()
randcnt = 0
End If
Return r
End Function
 
' // Get a random character in printable ASCII range
Function iRandA() As UByte
Return iRandom() Mod 95 +32
End Function
 
' // Seed ISAAC with a string
Sub iSeed(seed As String, flag As Long)
Dim As ULong i, m = Len(seed) -1
For i = 0 To 255
mm(i) = 0
Next
For i = 0 To 255
If i > m Then
randrsl(i) = 0
Else
randrsl(i) = seed[i]
End If
Next
randinit(flag)
End Sub
 
' // maximum length of message
'#define MAXMSG 4096
#Define _MOD_ 95 ' mod is FreeBASIC keyword
#Define _START_ 32 ' start is used as variable name
 
' // cipher modes for Caesar
Enum ciphermode
mEncipher
mDecipher
mNone
End Enum
 
' // XOR cipher on random stream. Output: ASCII string
' no maximum lenght for input and output string
Function Vernam(msg As String) As String
Dim As ULong i
Dim As String v
For i = 0 To Len(msg) -1
v += Chr(iRandA() Xor msg[i])
Next
Return v
End Function
 
' // Caesar-shift a printable character
Function Ceasar(m As ciphermode, ch As UByte, shift As UByte, modulo As UByte, _
start As UByte) As UByte
' FreeBASIC Mod does not handle negative numbers correctly
' also there is litte problem with shift (declared UByte)
' the IIF() statement helps with shift
' to avoid a negative n a 8 times modulo is added
' modulo * 8 get translateted by FreeBASIC to modulo shl 3
Dim As Long n = (ch - start) + IIf(m = mDecipher, -shift, shift) + modulo * 8
n = n Mod modulo
Return start + n
End Function
 
' // Caesar-shift a string on a pseudo-random stream
Function CeasarStr(m As ciphermode, msg As String, modulo As UByte, _
start As UByte) As String
Dim As Long i
Dim As String v
For i = 0 To Len(msg) -1
v += Chr(Ceasar(m, msg[i], iRandA(), modulo, start))
Next
Return v
End Function
 
' ------=< MAIN >=------
 
Dim As Long n, l
Dim As String msg = "a Top Secret secret"
Dim As String key = "this is my secret key"
 
Dim As String vctx, vptx
Dim As String cctx, cptx
 
l = Len(msg)
' // Encrypt: Vernam XOR
iSeed(key, 1)
vctx = Vernam(msg)
' // Encrypt: Caesar
cctx = CeasarStr(mEncipher, msg, _mod_, _start_)
' // Decrypt: Vernam XOR
iSeed(key, 1)
vptx = Vernam(vctx)
' // Decrypt: Caesar
cptx = CeasarStr(mDecipher, cctx, _mod_, _start_)
Print "message: "; msg
Print " key: "; key
Print " XOR: ";
' // Output Vernam ciphertext as a string of hex digits
For n = 0 To l -1
Print Hex(vctx[n], 2);
Next
Print
' // Output Vernam decrypted plaintext
Print "XOR dcr: "; vptx
' // Caesar
Print " MOD: ";
' // Output Caesar ciphertext as a string of hex digits
For n= 0 To l -1
Print Hex(cctx[n], 2);
Next
Print
' // Output Caesar decrypted plaintext
Print "MOD dcr: " ; cptx
 
' empty keyboard buffer
While InKey <> "" : Wend
Print : Print "hit any key to end program"
Sleep
End</syntaxhighlight>
{{out}}
<pre>message: a Top Secret secret
key: this is my secret key
XOR: 1C0636190B1260233B35125F1E1D0E2F4C5422
XOR dcr: a Top Secret secret
MOD: 734270227D36772A783B4F2A5F206266236978
MOD dcr: a Top Secret secret</pre>
 
=={{header|C}}==
At the top is Bob Jenkins' reference code for ISAAC.
Below and in main() is the task's complete solution for XOR and MOD.
<syntaxhighlight lang="c">
<lang C>
/* Known to compile and work with tcc in win32 & gcc on Linux (with warnings)
------------------------------------------------------------------------------
Line 295 ⟶ 507:
return 0;
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 304 ⟶ 516:
MOD : 734270227D36772A783B4F2A5F206266236978
MOD dcr: a Top Secret secret
</pre>
 
=={{header|C sharp}}==
XOR with decryption check.
<syntaxhighlight lang="c sharp">
using System;
 
namespace cipher {
 
static class Cipher {
 
// external results
static uint[] randrsl = new uint[256];
static uint randcnt;
// internal state
static uint[] mm = new uint[256];
static uint aa=0, bb=0, cc=0;
 
 
static void isaac() {
uint i,x,y;
cc++; // cc just gets incremented once per 256 results
bb+=cc; // then combined with bb
 
for (i=0; i<=255; i++) {
x = mm[i];
switch (i & 3) {
case 0: aa = aa ^ (aa << 13); break;
case 1: aa = aa ^ (aa >> 6); break;
case 2: aa = aa ^ (aa << 2); break;
case 3: aa = aa ^ (aa >> 16); break;
}
aa = mm[(i+128) & 255] + aa;
y = mm[(x >> 2) & 255] + aa + bb;
mm[i] = y;
bb = mm[(y >> 10) & 255] + x;
randrsl[i]= bb;
}
}
 
 
// if (flag==TRUE), then use the contents of randrsl[] to initialize mm[].
static void mix(ref uint a, ref uint b, ref uint c, ref uint d, ref uint e, ref uint f, ref uint g, ref uint h) {
a = a ^ b << 11; d+=a; b+=c;
b = b ^ c >> 2; e+=b; c+=d;
c = c ^ d << 8; f+=c; d+=e;
d = d ^ e >> 16; g+=d; e+=f;
e = e ^ f << 10; h+=e; f+=g;
f = f ^ g >> 4; a+=f; g+=h;
g = g ^ h << 8; b+=g; h+=a;
h = h ^ a >> 9; c+=h; a+=b;
}
 
 
static void Init(bool flag) {
short i; uint a,b,c,d,e,f,g,h;
 
aa=0; bb=0; cc=0;
a=0x9e3779b9; b=a; c=a; d=a;
e=a; f=a; g=a; h=a;
 
for (i=0; i<=3; i++) // scramble it
mix(ref a,ref b,ref c,ref d,ref e,ref f,ref g,ref h);
i=0;
do { // fill in mm[] with messy stuff
if (flag) { // use all the information in the seed
a+=randrsl[i ]; b+=randrsl[i+1]; c+=randrsl[i+2]; d+=randrsl[i+3];
e+=randrsl[i+4]; f+=randrsl[i+5]; g+=randrsl[i+6]; h+=randrsl[i+7];
} // if flag
mix(ref a,ref b,ref c,ref d,ref e,ref f,ref g,ref h);
mm[i ]=a; mm[i+1]=b; mm[i+2]=c; mm[i+3]=d;
mm[i+4]=e; mm[i+5]=f; mm[i+6]=g; mm[i+7]=h;
i+=8;
}
while (i<255);
 
if (flag) {
// do a second pass to make all of the seed affect all of mm
i=0;
do {
a+=mm[i ]; b+=mm[i+1]; c+=mm[i+2]; d+=mm[i+3];
e+=mm[i+4]; f+=mm[i+5]; g+=mm[i+6]; h+=mm[i+7];
mix(ref a,ref b,ref c,ref d,ref e,ref f,ref g,ref h);
mm[i ]=a; mm[i+1]=b; mm[i+2]=c; mm[i+3]=d;
mm[i+4]=e; mm[i+5]=f; mm[i+6]=g; mm[i+7]=h;
i+=8;
}
while (i<255);
}
isaac(); // fill in the first set of results
randcnt=0; // prepare to use the first set of results
}
 
 
// Seed ISAAC with a string
static void Seed(string seed, bool flag) {
for (int i=0; i<256; i++) mm[i]=0;
for (int i=0; i<256; i++) randrsl[i]=0;
int m = seed.Length;
for (int i=0; i<m; i++) {
randrsl[i] = seed[i];
}
// initialize ISAAC with seed
Init(flag);
}
 
 
// Get a random 32-bit value
static uint Random() {
uint result = randrsl[randcnt];
randcnt++;
if (randcnt>255) {
isaac(); randcnt=0;
}
return result;
}
 
 
// Get a random character in printable ASCII range
static byte RandA() {
return (byte)(Random() % 95 + 32);
}
 
 
// XOR encrypt on random stream. Output: ASCII byte array
static byte[] Vernam(string msg)
{
int n,l;
byte[] v = new byte[msg.Length];
l = msg.Length;
// XOR message
for (n=0; n<l; n++) {
v[n] = (byte) (RandA() ^ (byte)msg[n]);
}
return v;
}
 
public static void Main() {
string msg = "a Top Secret secret";
string key = "this is my secret key";
byte[] xctx= new byte[msg.Length];
byte[] xptx= new byte[msg.Length];
string xtcx= "*******************";
string xtpx= "*******************";
Seed(key,true);
// XOR encrypt
xctx = Vernam(msg);
xtcx = System.Text.Encoding.ASCII.GetString(xctx);
// XOR decrypt
Seed(key,true);
xptx = Vernam(xtcx);
xtpx = System.Text.Encoding.ASCII.GetString(xptx);
Console.WriteLine("Message: "+msg);
Console.WriteLine("Key : "+key);
Console.Write ("XOR : ");
// output ciphertext as a string of hexadecimal digits
for (int n=0; n<xctx.Length; n++) Console.Write("{0:X2}", xctx[n]);
Console.WriteLine("\nXOR dcr: "+xtpx);
}
}
}
</syntaxhighlight>
{{out}}
<pre>
Message: a Top Secret secret
Key : this is my secret key
XOR : 1C0636190B1260233B35125F1E1D0E2F4C5422
XOR dcr: a Top Secret secret
</pre>
 
=={{header|C++}}==
{{trans|Modula-2}}
<langsyntaxhighlight lang="cpp">
#include <iomanip>
#include <iostream>
Line 511 ⟶ 894:
cout << "MOD dcr: " << modPlainText << endl;
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 520 ⟶ 903:
XOR dcr: a Top Secret secret
MOD dcr: a Top Secret secret
</pre>
 
=={{header|C sharp}}==
XOR with decryption check.
<lang C sharp>
using System;
 
namespace cipher {
 
static class Cipher {
 
// external results
static uint[] randrsl = new uint[256];
static uint randcnt;
// internal state
static uint[] mm = new uint[256];
static uint aa=0, bb=0, cc=0;
 
 
static void isaac() {
uint i,x,y;
cc++; // cc just gets incremented once per 256 results
bb+=cc; // then combined with bb
 
for (i=0; i<=255; i++) {
x = mm[i];
switch (i & 3) {
case 0: aa = aa ^ (aa << 13); break;
case 1: aa = aa ^ (aa >> 6); break;
case 2: aa = aa ^ (aa << 2); break;
case 3: aa = aa ^ (aa >> 16); break;
}
aa = mm[(i+128) & 255] + aa;
y = mm[(x >> 2) & 255] + aa + bb;
mm[i] = y;
bb = mm[(y >> 10) & 255] + x;
randrsl[i]= bb;
}
}
 
 
// if (flag==TRUE), then use the contents of randrsl[] to initialize mm[].
static void mix(ref uint a, ref uint b, ref uint c, ref uint d, ref uint e, ref uint f, ref uint g, ref uint h) {
a = a ^ b << 11; d+=a; b+=c;
b = b ^ c >> 2; e+=b; c+=d;
c = c ^ d << 8; f+=c; d+=e;
d = d ^ e >> 16; g+=d; e+=f;
e = e ^ f << 10; h+=e; f+=g;
f = f ^ g >> 4; a+=f; g+=h;
g = g ^ h << 8; b+=g; h+=a;
h = h ^ a >> 9; c+=h; a+=b;
}
 
 
static void Init(bool flag) {
short i; uint a,b,c,d,e,f,g,h;
 
aa=0; bb=0; cc=0;
a=0x9e3779b9; b=a; c=a; d=a;
e=a; f=a; g=a; h=a;
 
for (i=0; i<=3; i++) // scramble it
mix(ref a,ref b,ref c,ref d,ref e,ref f,ref g,ref h);
i=0;
do { // fill in mm[] with messy stuff
if (flag) { // use all the information in the seed
a+=randrsl[i ]; b+=randrsl[i+1]; c+=randrsl[i+2]; d+=randrsl[i+3];
e+=randrsl[i+4]; f+=randrsl[i+5]; g+=randrsl[i+6]; h+=randrsl[i+7];
} // if flag
mix(ref a,ref b,ref c,ref d,ref e,ref f,ref g,ref h);
mm[i ]=a; mm[i+1]=b; mm[i+2]=c; mm[i+3]=d;
mm[i+4]=e; mm[i+5]=f; mm[i+6]=g; mm[i+7]=h;
i+=8;
}
while (i<255);
 
if (flag) {
// do a second pass to make all of the seed affect all of mm
i=0;
do {
a+=mm[i ]; b+=mm[i+1]; c+=mm[i+2]; d+=mm[i+3];
e+=mm[i+4]; f+=mm[i+5]; g+=mm[i+6]; h+=mm[i+7];
mix(ref a,ref b,ref c,ref d,ref e,ref f,ref g,ref h);
mm[i ]=a; mm[i+1]=b; mm[i+2]=c; mm[i+3]=d;
mm[i+4]=e; mm[i+5]=f; mm[i+6]=g; mm[i+7]=h;
i+=8;
}
while (i<255);
}
isaac(); // fill in the first set of results
randcnt=0; // prepare to use the first set of results
}
 
 
// Seed ISAAC with a string
static void Seed(string seed, bool flag) {
for (int i=0; i<256; i++) mm[i]=0;
for (int i=0; i<256; i++) randrsl[i]=0;
int m = seed.Length;
for (int i=0; i<m; i++) {
randrsl[i] = seed[i];
}
// initialize ISAAC with seed
Init(flag);
}
 
 
// Get a random 32-bit value
static uint Random() {
uint result = randrsl[randcnt];
randcnt++;
if (randcnt>255) {
isaac(); randcnt=0;
}
return result;
}
 
 
// Get a random character in printable ASCII range
static byte RandA() {
return (byte)(Random() % 95 + 32);
}
 
 
// XOR encrypt on random stream. Output: ASCII byte array
static byte[] Vernam(string msg)
{
int n,l;
byte[] v = new byte[msg.Length];
l = msg.Length;
// XOR message
for (n=0; n<l; n++) {
v[n] = (byte) (RandA() ^ (byte)msg[n]);
}
return v;
}
 
public static void Main() {
string msg = "a Top Secret secret";
string key = "this is my secret key";
byte[] xctx= new byte[msg.Length];
byte[] xptx= new byte[msg.Length];
string xtcx= "*******************";
string xtpx= "*******************";
Seed(key,true);
// XOR encrypt
xctx = Vernam(msg);
xtcx = System.Text.Encoding.ASCII.GetString(xctx);
// XOR decrypt
Seed(key,true);
xptx = Vernam(xtcx);
xtpx = System.Text.Encoding.ASCII.GetString(xptx);
Console.WriteLine("Message: "+msg);
Console.WriteLine("Key : "+key);
Console.Write ("XOR : ");
// output ciphertext as a string of hexadecimal digits
for (int n=0; n<xctx.Length; n++) Console.Write("{0:X2}", xctx[n]);
Console.WriteLine("\nXOR dcr: "+xtpx);
}
}
}
</lang>
{{out}}
<pre>
Message: a Top Secret secret
Key : this is my secret key
XOR : 1C0636190B1260233B35125F1E1D0E2F4C5422
XOR dcr: a Top Secret secret
</pre>
 
=={{header|Common Lisp}}==
<langsyntaxhighlight lang="lisp">(defpackage isaac
(:use cl))
 
Line 936 ⟶ 1,148:
(terpri)
(format t "MOD dcr: ~a~%" cptx))))
(values))</langsyntaxhighlight>
{{out}}
<pre>ISAAC> (main-test)
Line 948 ⟶ 1,160:
=={{header|D}}==
Improved from the C# version. XOR with decryption check.
<langsyntaxhighlight lang="d">import std.algorithm: min;
import std.algorithm: copy;
import std.typetuple: TypeTuple;
Line 1,112 ⟶ 1,324:
 
writeln("Decrypted: ", decrypted.assumeUTF);
}</langsyntaxhighlight>
{{out}}
<pre>Message : a Top Secret secret
Line 1,121 ⟶ 1,333:
=={{header|Delphi}}==
Translation of Pascal.
<syntaxhighlight lang="delphi">
<lang Delphi>
{$apptype console}
PROGRAM RosettaIsaac;
Line 1,320 ⟶ 1,532:
Writeln('MOD : ',mctx);
END.
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,332 ⟶ 1,544:
{{works with|node.js|0.10.32}}
{{trans|C#}}
<langsyntaxhighlight lang="ecmascript">randrsl = new Uint32Array(256);
randcnt = 0;
mm = new Uint32Array(256);
Line 1,447 ⟶ 1,659:
xptx = z[1];
console.log('xor: '+printable_hex(xctx))
console.log('decrypted: '+xptx)</langsyntaxhighlight>
{{out}}
<pre>
Line 1,455 ⟶ 1,667:
decrypted: a Top Secret secret
</pre>
=={{header|FreeBASICForth}}==
<syntaxhighlight lang="forth">
{{trans|C}}
Tested for VFX Forth and GForth 64bit in Linux
<lang freebasic>' version 03-11-2016
The code was based on and debugged v python
' compile with: fbc -s console
 
\ ******* Words for 32 bit fetching and storing *******
Dim Shared As UInteger<32> randrsl(256), randcnt
\ * Implement words for 32 bit fields (assuming 64 bit Forth) *
Static Shared As UInteger<32> mm(256)
\ *************************************************************
Static Shared As UInteger<32> aa, bb ,cc
 
: halves 4 * ; \ half a cell.
Sub ISAAC()
 
\ VFX Forth
Dim As UInteger<32> i, x, y
\ : h@ L@ ; : h! L! ; : h+! L+! ;
\ GFORTH
: h@ UL@ ; : h! L! ; : h+! DUP h@ ROT + SWAP h! ;
\ a 32 bit Forth
\ : h@ @ ; : h! ! ; : h+! +! ;
 
: half-array \ n <'name'> -- ; DOES> n -- a ;
cc = cc + 1
\ Use: 8 half-array test - creates an array of 8 32 bit elements.
bb = bb + cc
\ Does> 4 test - returns the address of the 4th element of test.
CREATE HERE SWAP halves DUP ALLOT ERASE
DOES> SWAP halves + ;
 
\ ***** Words to implement an isaac rng *****
For i = 0 To 256 -1
8 half-array ]init-state
x = mm(i)
Select Case (i Mod 4)
Case 0 : aa = aa Xor (aa Shl 13)
Case 1 : aa = aa Xor (aa Shr 6)
Case 2 : aa = aa Xor (aa Shl 2)
Case 3 : aa = aa Xor (aa Shr 16)
End Select
aa = mm((i+128) Mod 256) + aa
y = mm((x Shr 2) Mod 256) + aa + bb : mm(i) = y
bb = mm((y Shr 10) Mod 256) + x : randrsl(i) = bb
Next
 
: init+! \ ix-tgt ix-src -- ;
randcnt = 0
]init-state h@ SWAP ]init-state h+! ;
 
: init-right-xor! \ ix-tgt ix-src shift-bits -- ;
End Sub
SWAP ]init-state h@ SWAP RSHIFT SWAP ]init-state TUCK h@ XOR SWAP h! ;
 
: init-left-xor! \ ix-tgt ix-src shift-bits -- ;
SWAP ]init-state h@ SWAP LSHIFT SWAP ]init-state TUCK h@ XOR SWAP h! ;
 
: mix
#Macro mix(a, b, c, d, e, f, g, h)
0 1 11 init-left-xor! 3 0 init+! 1 2 init+!
1 2 2 init-right-xor! 4 1 init+! 2 3 init+!
2 3 8 init-left-xor! 5 2 init+! 3 4 init+!
3 4 16 init-right-xor! 6 3 init+! 4 5 init+!
4 5 10 init-left-xor! 7 4 init+! 5 6 init+!
5 6 4 init-right-xor! 0 5 init+! 6 7 init+!
6 7 8 init-left-xor! 1 6 init+! 7 0 init+!
7 0 9 init-right-xor! 2 7 init+! 0 1 init+! ;
 
\ State variables and arrays
a Xor= b Shl 11 : d += a : b += c
VARIABLE aa b Xor= cVARIABLE Shrbb 2 :VARIABLE ecc += b :VARIABLE c += drand-count
256 half-array ]mm
c Xor= d Shl 8 : f += c : d += e
256 half-array ]result
d Xor= e Shr 16 : g += d : e += f
e Xor= f Shl 10 : h += e : f += g
f Xor= g Shr 4 : a += f : g += h
g Xor= h Shl 8 : b += g : h += a
h Xor= a Shr 9 : c += h : a += b
 
\ Jump table of xts used in isaac-iteration
#EndMacro
: shift-xor0 aa DUP h@ DUP 13 LSHIFT XOR SWAP h! ; \ -- ;
: shift-xor1 aa DUP h@ DUP 6 RSHIFT XOR SWAP h! ; \ -- ;
: shift-xor2 aa DUP h@ DUP 2 LSHIFT XOR SWAP h! ; \ -- ;
: shift-xor3 aa DUP h@ DUP 16 RSHIFT XOR SWAP h! ; \ -- ;
 
HERE
Sub randinit(flag As Long)
' shift-xor0 , ' shift-xor1 , ' shift-xor2 , ' shift-xor3 ,
CONSTANT shift-xor-xts
 
: ]execute-shift-xorn \ ix -- ; Executes the xt in shift-xor-xts
Dim As Long i
CELLS shift-xor-xts + @ EXECUTE ;
Dim As UInteger<32> a = &H9e3779b9 '/* the golden ratio *
Dim As UInteger<32> b = &H9e3779b9
Dim As UInteger<32> c = &H9e3779b9
Dim As UInteger<32> d = &H9e3779b9
Dim As UInteger<32> e = &H9e3779b9
Dim As UInteger<32> f = &H9e3779b9
Dim As UInteger<32> g = &H9e3779b9
Dim As UInteger<32> h = &H9e3779b9
aa = 0 : bb = 0 : cc = 0
 
: isaac-iteration \ -- ;
For i = 0 To 3
1 cc h+! cc h@ mix(a, b, c, d, e, f, g,bb h)+!
256 0 DO \ Python code
Next
I ]mm h@ \ x = mm[i] Store mm[i] on the stack
 
ForI i3 =AND ]execute-shift-xorn 0 To 255 Step 8
\ Executes shift-xor0 .. 3 from shift-xor-xts above.
If flag = 1 Then
a += randrsl(i ) : b += randrsl(i +1)
c += randrsl(i +2) : d += randrsl(i +3)
e += randrsl(i +4) : f += randrsl(i +5)
g += randrsl(i +6) : h += randrsl(i +7)
 
aa DUP h@ I 128 XOR ]mm mix(a,h@ b,+ c,SWAP d,h! e, f,\ g,aa h= (mm[i^128] + aa)
mm(i ) = a : mm(i +1) = b : mm(i +2) = c : mm(i +3) = d
mm(i +4) = e : mm(i +5) = f : mm(i +6) = g : mm(i +7) = h
End If
Next
 
DUP 2 RSHIFT 0xFF AND ]mm h@ aa h@ + bb h@ + \ mm[(x>>2) & 0xFF] + aa + bb)
If flag = 1 Then
DUP I ]mm h! For \ y = mm[i] = 0; Store in ]mm leave Toy 255on Stepthe 8stack
a += mm(i ) : b += mm(i +1)
c += mm(i +2) : d += mm(i +3)
e += mm(i +4) : f += mm(i +5)
g += mm(i +6) : h += mm(i +7)
 
10 RSHIFT 0xFF AND ]mm h@ + mix\ mm[(a,y>>10) b,& c,0xFF] d,+ e, f, g, hx)
DUP bb h! I ]result h! \ mm(result[i] )= a : mm(i +1)self.bb = b; :store mm(iin +2)bb =and c : mm(result[i +3) = d]
mm(i +4)= e : mm(i +5) = f : mm(i +6) = g : mm(i +7) = h
Next
End If
 
LOOP
ISAAC()
0 rand-count ! ;
randcnt = 0
 
256 half-array ]seed
End Sub
: zero-fill \ a ct -- ;
halves ERASE ;
 
: seed-mt 0 ]seed 256 zero-fill ;
' // Get a random 32-bit value 0..MAXINT
Function iRandom() As UInteger<32>
 
: string>seed \ a ct -- ;
Dim As UInteger<32> r = randrsl(randcnt)
seed-mt 256 MIN ]seed 0 ]seed ?DO COUNT I h! 4 +LOOP DROP ;
randcnt += 1
If randcnt > 255 Then
ISAAC()
randcnt = 0
End If
 
: mm-mt 0 ]mm 256 zero-fill ;
Return r
: init-vars 0 aa ! 0 bb ! 0 cc ! 256 rand-count ! ;
: res-mt 0 ]result 256 zero-fill ;
 
: base-init-state
End Function
8 ]init-state 0 ]init-state DO 0x9e3779b9 i h! 4 +LOOP
mix mix mix mix ;
 
: init>mm-ix \ ix -- ;
' // Get a random character in printable ASCII range
0 ]init-state SWAP ]mm 8 halves MOVE ;
Function iRandA() As UByte
 
: init>mm \ -- ;
Return iRandom() Mod 95 +32
256 0 DO mix I init>mm-ix 8 +LOOP
0 aa h! 0 bb h! 0 cc h! ;
 
: default-seed \ -- ;
End Function
base-init-state init>mm ;
 
: seed>init-state>mm
' // Seed ISAAC with a string
256 0 DO
Sub iSeed(seed As String, flag As Long)
8 0 DO I J + ]seed h@ I ]init-state h+! LOOP
mix
0 ]init-state I ]mm 8 halves MOVE
8 +LOOP ;
 
: init-mm-mix
Dim As ULong i, m = Len(seed) -1
256 0 DO
8 0 DO I J + ]mm h@ I ]init-state h+! LOOP
mix
I init>mm-ix
8 +LOOP ;
 
: string-seed \ str ct -- ;
For i = 0 To 255
string>seed base-init-state seed>init-state>mm
mm(i) = 0
init-mm-mix init-vars res-mt ;
Next
 
: random-next \ -- h ; 32 bit result
For i = 0 To 255
rand-count @ 255 > IF isaac-iteration 0 rand-count ! THEN
rand-count @ DUP ]result h@ SWAP 1+ rand-count ! ;
 
: rand-char If\ i-- >ch m Then;
random-next 95 MOD 32 + ;
randrsl(i) = 0
Else
randrsl(i) = seed[i]
End If
 
\ Encode, Decode and display.
Next
 
\ Working buffers
randinit(flag)
1024 CONSTANT buff-size
CREATE buff-in buff-size ALLOT
CREATE xor-out buff-size ALLOT
CREATE caesar-out buff-size ALLOT
 
: buff-count \ adr -- addr+cell count ; \ Prepares buff for TYPE
End Sub
DUP CELL + SWAP @ ;
 
: buff. buff-count TYPE ; \ addr -- ;
' // maximum length of message
'#define MAXMSG 4096
#Define _MOD_ 95 ' mod is FreeBASIC keyword
#Define _START_ 32 ' start is used as variable name
 
: byte>hexstr \ b -- str ct ; \ Generates a 2 character hex string.
' // cipher modes for Caesar
BASE @ SWAP HEX 0 <# # # #> ROT BASE ! ;
Enum ciphermode
mEncipher
mDecipher
mNone
End Enum
 
: buff-hex. \ addr --- ;
' // XOR cipher on random stream. Output: ASCII string
buff-count BOUNDS ?DO I C@ byte>hexstr TYPE LOOP ;
' no maximum lenght for input and output string
Function Vernam(msg As String) As String
 
: buff-empty 0 SWAP ! ; \ addr -- ; \ Empty the buffer. Sets length to zero.
Dim As ULong i
Dim As String v
 
: char-append \ ch adr -- ; \ Append ch to the buffer
For i = 0 To Len(msg) -1
tuck buff-count + C! 1 SWAP +! ;
v += Chr(iRandA() Xor msg[i])
Next
 
: buff-copy \ src dest -- ; \ Copy buffer to buffer
Return v
OVER @ CELL + MOVE ;
 
: buff-fill \ str ct buff -- ; \ Fill buffer with the contents of str ct
End Function
2DUP ! CELL + SWAP MOVE ;
 
\ ***** XOR encode/decode *****
' // Caesar-shift a printable character
: xor-byte \ b -- b' ;
Function Ceasar(m As ciphermode, ch As UByte, shift As UByte, modulo As UByte, _
rand-char XOR ;
start As UByte) As UByte
 
: xor-code \ str ct -- ;
' FreeBASIC Mod does not handle negative numbers correctly
xor-out buff-empty
' also there is litte problem with shift (declared UByte)
BOUNDS ?DO I C@ xor-byte xor-out char-append LOOP ;
' the IIF() statement helps with shift
' to avoid a negative n a 8 times modulo is added
' modulo * 8 get translateted by FreeBASIC to modulo shl 3
Dim As Long n = (ch - start) + IIf(m = mDecipher, -shift, shift) + modulo * 8
n = n Mod modulo
Return start + n
 
: init-rng" [CHAR] " WORD COUNT string-seed ;
End Function
 
: xor-code-with" \ str ct <key"> -- ; str ct points to the text to encode
' // Caesar-shift a string on a pseudo-random stream
\ Use: s" Message" encode-xor-key" This is the key."
Function CeasarStr(m As ciphermode, msg As String, modulo As UByte, _
\ Prints the encoded bytes in hex to the terminal.
start As UByte) As String
init-rng" xor-code ;
 
\ ***** Caesar encode/decode *****
Dim As Long i
DEFER op \ ' + for encode, ' - for decode in caesar-code-ch
Dim As String v
 
: encode ['] + IS op ; \ Add the offset while encoding.
For i = 0 To Len(msg) -1
: decode ['] - IS op ; \ Substract it to decode
v += Chr(Ceasar(m, msg[i], iRandA(), modulo, start))
Next
 
: caesar-code-ch \ c -- c' ;
Return v
rand-char op 32 - 95 MOD
BEGIN DUP 0< WHILE 95 + REPEAT 32 + ;
 
: caesar \ str ct -- ;
End Function
\ The direction of caesar-code is modified by the encode / decode words
\ eg. encode s" Message" caesar
\ decode s" DntP8hg" caesar
caesar-out buff-empty
BOUNDS ?DO I C@ caesar-code-ch caesar-out char-append LOOP ;
 
: caesar-with" \ str ct <key" -- ;
' ------=< MAIN >=------
\ The direction of caesar-code is modified by the encode / decode words
\ eg. encode s" Message" caesar-with" Key"
\ decode s" DntP8hg" caesar-with" Key"
init-rng" caesar ;
 
\ ***** Demonstrate the encode/decode working *****
Dim As Long n, l
Dim: Asmessage String msg = s" a Top Secret secret" ;
Dim As String key = "this is my secret key"
 
: out>in \ buff-out -- buff-in' count ;
Dim As String vctx, vptx
buff-in buff-copy buff-in buff-count ;
Dim As String cctx, cptx
 
: xor>in xor-out out>in ; \ -- buff-in' ct ;
l = Len(msg)
: caesar>in caesar-out out>in ; \ -- buff-in' ct ;
' // Encrypt: Vernam XOR
iSeed(key, 1)
vctx = Vernam(msg)
' // Encrypt: Caesar
cctx = CeasarStr(mEncipher, msg, _mod_, _start_)
' // Decrypt: Vernam XOR
iSeed(key, 1)
vptx = Vernam(vctx)
' // Decrypt: Caesar
cptx = CeasarStr(mDecipher, cctx, _mod_, _start_)
Print "message: "; msg
Print " key: "; key
Print " XOR: ";
' // Output Vernam ciphertext as a string of hex digits
For n = 0 To l -1
Print Hex(vctx[n], 2);
Next
Print
' // Output Vernam decrypted plaintext
Print "XOR dcr: "; vptx
' // Caesar
Print " MOD: ";
' // Output Caesar ciphertext as a string of hex digits
For n= 0 To l -1
Print Hex(cctx[n], 2);
Next
Print
' // Output Caesar decrypted plaintext
Print "MOD dcr: " ; cptx
 
: examples
' empty keyboard buffer
CR ." Raw message : " message TYPE
While InKey <> "" : Wend
CR ." First encode."
Print : Print "hit any key to end program"
s" this is my secret key" string-seed \ Set key
Sleep
message xor-code
End</lang>
CR ." XOR encoded as hex : " xor-out buff-hex.
message encode caesar
CR ." Caesar encoded as hex: " caesar-out buff-hex.
CR ." Now decode "
s" this is my secret key" string-seed \ Set key
xor>in xor-code
CR ." XOR decoded : " xor-out buff.
caesar>in decode caesar
CR ." Caesar decoded : " caesar-out buff. ;
</syntaxhighlight>
{{out}}
<pre>
<pre>message: a Top Secret secret
message key:xor-code-with" this is my secret key" ok
CR ." XOR encoded as hex : " xor-out buff-hex.
XOR: 1C0636190B1260233B35125F1E1D0E2F4C5422
XOR encoded as hex : 1C0636190B1260233B35125F1E1D0E2F4C5422 ok
XOR dcr: a Top Secret secret
ok
MOD: 734270227D36772A783B4F2A5F206266236978
message encode caesar ok
MOD dcr: a Top Secret secret</pre>
CR ." Caesar encoded as hex: " caesar-out buff-hex.
Caesar encoded as hex: 734270227D36772A783B4F2A5F206266236978 ok
ok
ok
xor>in xor-code-with" this is my secret key" ok
CR ." XOR decoded : " xor-out buff.
XOR decoded : a Top Secret secret ok
ok
caesar>in decode caesar ok
CR ." Caesar decoded : " caesar-out buff.
Caesar decoded : a Top Secret secret ok
ok
examples
Raw message : a Top Secret secret
First encode.
XOR encoded as hex : 1C0636190B1260233B35125F1E1D0E2F4C5422
Caesar encoded as hex: 734270227D36772A783B4F2A5F206266236978
Now decode
XOR decoded : a Top Secret secret
Caesar decoded : a Top Secret secret ok
</pre>
 
=={{header|Go}}==
XOR version
<langsyntaxhighlight lang="go">package main
 
import "fmt"
Line 1,824 ⟶ 2,043:
}
return fmt.Sprintf("%X", b)
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,833 ⟶ 2,052:
 
=={{header|Haskell}}==
<langsyntaxhighlight Haskelllang="haskell">import Data.Array (Array, (!), (//), array, elems)
import Data.Word (Word, Word32)
import Data.Bits (shift, xor)
Line 1,967 ⟶ 2,186:
putStrLn $ "Key : " ++ key
putStrLn $ "XOR : " ++ hexify ver
putStrLn $ "XOR dcr: " ++ unver</langsyntaxhighlight>
{{out}}
<pre>Message: a Top Secret secret
Line 1,981 ⟶ 2,200:
It is possible in Haxe to create your own 32bit unsigned type,
but that is outside this exercise.
<syntaxhighlight lang="haxe">
<lang Haxe>
package src ;
import haxe.Int32;
Line 2,143 ⟶ 2,362:
}
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,153 ⟶ 2,372:
MOD dcr: a Top Secret secret
</pre>
 
=={{header|J}}==
{{trans|C}}
In this draft, only the XOR implementation (vernam) is implemented:
<syntaxhighlight lang="j">NB. bitwise logic on 32 bit unsigned values
ub4=: (#.33{.1)&|
xor=: ub4@(2b10110 b.)
shl=: ub4@(33 b.~)
add=: ub4@+
 
isaac=: {{
cc=: cc add 1
bb=: bb add cc
for_i.i.256 do.
aa=. aa xor aa shl 13 _6 2 _16{~4|i
X=. i{mm
aa=. aa add mm{~ 256| i+128
y=. aa add bb add mm{~ 256| X shl _2
randrsl=: randrsl i}~ bb=. X add mm{~ 256| y shl _10
end.
randcnt=: 0
}}
mix=: {{
b=: b add c [ d=: d add a=: a xor b shl 11
c=: c add d [ e=: e add b=: b xor c shl _2
d=: d add e [ f=: f add c=: c xor d shl 8
e=: e add f [ g=: g add d=: d xor e shl _16
f=: f add g [ h=: h add e=: e xor f shl 10
g=: g add h [ a=: a add f=: f xor g shl _4
h=: h add a [ b=: b add g=: g xor h shl 8
a=: a add b [ c=: c add h=: h xor a shl _9
}}
 
randinit=: {{
aa=: bb=: cc=: 0
a=: b=: c=: d=: e=: f=: g=: h=: 16b9e3779b9
mix^:4''
if. y do.
for_i. _8]\i.256 do.
mix 'a b c d e f g h'=: (a,b,c,d,e,f,g,h) add i{randrsl
mm=: mm i}~ a,b,c,d,e,f,g,h
end.
for_i. _8]\i.256 do.
mix 'a b c d e f g h'=: (a,b,c,d,e,f,g,h) add i{mm
mm=: mm i}~ a,b,c,d,e,f,g,h
end.
else.
for_i. _8]\i.256 do.
mix ''
mm=: mm i}~ a,b,c,d,e,f,g,h
end.
end.
isaac''
}}
 
iRandom=: {{
r=. randcnt { randrsl
if. 255 < randcnt=: randcnt+1 do. isaac'' end.
r
}}
 
iRandA=: {{ 7 u: 32+95|iRandom^:(1+i.y)'' }}
 
iSeed=: {{ NB. y: seed, x: flag
0 iSeed y
:
mm=: 256#0
randrsl=: 256{.3 u: y
randinit x
}}
 
vernam=: {{ y xor&.(3&u:) iRandA #y }}</syntaxhighlight>
 
Task example:<syntaxhighlight lang="j"> ,hfd 3 u:E=: vernam 'a Top Secret secret' [ 1 iSeed 'this is my secret key'
1c0636190b1260233b35125f1e1d0e2f4c5422
vernam E [ 1 iSeed 'this is my secret key'
a Top Secret secret</syntaxhighlight>
 
=={{header|Java}}==
Line 2,162 ⟶ 2,459:
This implementation extends the java.util.Random class, so it inherits methods that generate booleans, floats, doubles and longs, and can also generate numbers with Gaussian and uniform distribution. It can also be plugged in to standard library methods that receive a Random instance as a source of randomness. The toHexString() and main() methods are for demo purposes only and can be removed without changing main functionality.
 
<langsyntaxhighlight Javalang="java">import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.Random;
Line 2,386 ⟶ 2,683:
System.out.printf("MOD dcr: %s\n", caesarDecrypted);
}
}</langsyntaxhighlight>
 
=={{header|Julia}}==
<syntaxhighlight lang="julia">
<lang Julia>
"""
Julia translation of code from the following:
Line 2,570 ⟶ 2,867:
const key = "this is my secret key"
test(IState(), msg, key)
</syntaxhighlight>
</lang>
{{output}}<pre>
Message: a Top Secret secret
Line 2,580 ⟶ 2,877:
=={{header|Kotlin}}==
{{trans|C}}
<langsyntaxhighlight lang="scala">// version 1.1.3
 
/* external results */
Line 2,742 ⟶ 3,039:
println("MOD : ${cctx.toHexByteString()}")
println("MOD dcr : $cptx")
}</langsyntaxhighlight>
 
{{out}}
Line 2,752 ⟶ 3,049:
MOD : 734270227D36772A783B4F2A5F206266236978
MOD dcr : a Top Secret secret
</pre>
 
=={{header|Lua}}==
<syntaxhighlight lang="lua">#!/usr/bin/env lua
-- ISAAC - Lua 5.3
 
-- External Results
local randRsl = {};
local randCnt = 0;
 
-- Internal State
local mm = {};
local aa,bb,cc = 0,0,0;
 
-- Cap to maintain 32 bit maths
local cap = 0x100000000;
 
-- CipherMode
local ENCRYPT = 1;
local DECRYPT = 2;
 
function isaac()
 
cc = ( cc + 1 ) % cap; -- cc just gets incremented once per 256 results
bb = ( bb + cc ) % cap; -- then combined with bb
 
for i = 0,255 do
local x = mm[i];
local y;
local imod = i % 4;
if imod == 0 then aa = aa ~ (aa << 13);
elseif imod == 1 then aa = aa ~ (aa >> 6);
elseif imod == 2 then aa = aa ~ (aa << 2);
elseif imod == 3 then aa = aa ~ (aa >> 16);
end
aa = ( mm[(i+128)%256] + aa ) % cap;
y = ( mm[(x>>2) % 256] + aa + bb ) % cap;
mm[i] = y;
bb = ( mm[(y>>10)%256] + x ) % cap;
randRsl[i] = bb;
end
 
randCnt = 0; -- Prepare to use the first set of results.
 
end
 
function mix(a)
a[0] = ( a[0] ~ ( a[1] << 11 ) ) % cap; a[3] = ( a[3] + a[0] ) % cap; a[1] = ( a[1] + a[2] ) % cap;
a[1] = ( a[1] ~ ( a[2] >> 2 ) ) % cap; a[4] = ( a[4] + a[1] ) % cap; a[2] = ( a[2] + a[3] ) % cap;
a[2] = ( a[2] ~ ( a[3] << 8 ) ) % cap; a[5] = ( a[5] + a[2] ) % cap; a[3] = ( a[3] + a[4] ) % cap;
a[3] = ( a[3] ~ ( a[4] >> 16 ) ) % cap; a[6] = ( a[6] + a[3] ) % cap; a[4] = ( a[4] + a[5] ) % cap;
a[4] = ( a[4] ~ ( a[5] << 10 ) ) % cap; a[7] = ( a[7] + a[4] ) % cap; a[5] = ( a[5] + a[6] ) % cap;
a[5] = ( a[5] ~ ( a[6] >> 4 ) ) % cap; a[0] = ( a[0] + a[5] ) % cap; a[6] = ( a[6] + a[7] ) % cap;
a[6] = ( a[6] ~ ( a[7] << 8 ) ) % cap; a[1] = ( a[1] + a[6] ) % cap; a[7] = ( a[7] + a[0] ) % cap;
a[7] = ( a[7] ~ ( a[0] >> 9 ) ) % cap; a[2] = ( a[2] + a[7] ) % cap; a[0] = ( a[0] + a[1] ) % cap;
end
 
function randInit(flag)
 
-- The golden ratio in 32 bit
-- math.floor((((math.sqrt(5)+1)/2)%1)*2^32) == 2654435769 == 0x9e3779b9
local a = { [0] = 0x9e3779b9, 0x9e3779b9, 0x9e3779b9, 0x9e3779b9, 0x9e3779b9, 0x9e3779b9, 0x9e3779b9, 0x9e3779b9, };
 
aa,bb,cc = 0,0,0;
 
for i = 1,4 do mix(a) end -- Scramble it.
 
for i = 0,255,8 do -- Fill in mm[] with messy stuff.
if flag then -- Use all the information in the seed.
for j = 0,7 do
a[j] = ( a[j] + randRsl[i+j] ) % cap;
end
end
mix(a);
for j = 0,7 do
mm[i+j] = a[j];
end
end
 
if flag then
-- Do a second pass to make all of the seed affect all of mm.
for i = 0,255,8 do
for j = 0,7 do
a[j] = ( a[j] + mm[i+j] ) % cap;
end
mix(a);
for j = 0,7 do
mm[i+j] = a[j];
end
end
end
 
isaac(); -- Fill in the first set of results.
randCnt = 0; -- Prepare to use the first set of results.
 
end
 
-- Seed ISAAC with a given string.
-- The string can be any size. The first 256 values will be used.
function seedIsaac(seed,flag)
local seedLength = #seed;
for i = 0,255 do mm[i] = 0; end
for i = 0,255 do randRsl[i] = seed:byte(i+1,i+1) or 0; end
randInit(flag);
end
 
-- Get a random 32-bit value 0..MAXINT
function getRandom32Bit()
local result = randRsl[randCnt];
randCnt = randCnt + 1;
if randCnt > 255 then
isaac();
randCnt = 0;
end
return result;
end
 
-- Get a random character in printable ASCII range
function getRandomChar()
return getRandom32Bit() % 95 + 32;
end
 
-- Convert an ASCII string to a hexadecimal string.
function ascii2hex(source)
local ss = "";
for i = 1,#source do
ss = ss..string.format("%02X",source:byte(i,i));
end
return ss
end
 
-- XOR encrypt on random stream.
function vernam(msg)
local msgLength = #msg;
local destination = {};
for i = 1, msgLength do
destination[i] = string.char(getRandomChar() ~ msg:byte(i,i));
end
return table.concat(destination);
end
 
-- Caesar-shift a character <shift> places: Generalized Vigenere
function caesar(m, ch, shift, modulo, start)
local n
local si = 1
if m == DECRYPT then shift = shift*-1 ; end
n = (ch - start) + shift;
if n < 0 then si,n = -1,n*-1 ; end
n = ( n % modulo ) * si;
if n < 0 then n = n + modulo ; end
return start + n;
end
 
-- Vigenere mod 95 encryption & decryption.
function vigenere(msg,m)
local msgLength = #msg;
local destination = {};
for i = 1,msgLength do
destination[i] = string.char( caesar(m, msg:byte(i,i), getRandomChar(), 95, 32) );
end
return table.concat(destination);
end
 
function main()
local msg = "a Top Secret secret";
local key = "this is my secret key";
local xorCipherText, modCipherText, xorPlainText, modPlainText;
 
-- (1) Seed ISAAC with the key
seedIsaac(key, true);
-- (2) Encryption
-- (a) XOR (Vernam)
xorCipherText = vernam(msg);
-- (b) MOD (Vigenere)
modCipherText = vigenere(msg, ENCRYPT);
-- (3) Decryption
seedIsaac(key, true);
-- (a) XOR (Vernam)
xorPlainText = vernam(xorCipherText);
-- (b) MOD (Vigenere)
modPlainText = vigenere(modCipherText, DECRYPT);
-- Program output
print("Message: " .. msg);
print("Key : " .. key);
print("XOR : " .. ascii2hex(xorCipherText));
print("XOR dcr: " .. xorPlainText);
print("MOD : " .. ascii2hex(modCipherText));
print("MOD dcr: " .. modPlainText);
 
end
 
main()
</syntaxhighlight>
{{out}}
<pre>
Message: a Top Secret secret
Key : this is my secret key
XOR : 1c0636190b1260233b35125f1e1d0e2f4c5422
MOD : 734270227d36772a783b4f2a5f206266236978
XOR dcr: a Top Secret secret
MOD dcr: a Top Secret secret
</pre>
 
Line 2,758 ⟶ 3,256:
{{works with|ADW Modula-2|any (Compile with the linker option ''Console Application'').}}
I changed the identifiers to clearer ones and I changed the variables <code>a</code>, <code>b</code>, ..., <code>h</code> to an array, because they made my blood boil.
<langsyntaxhighlight lang="modula2">
MODULE RosettaIsaac;
 
Line 2,774 ⟶ 3,272:
TMode = (iEncrypt, iDecrypt);
TString = ARRAY [0 .. MaxStrLength - 1] OF CHAR;
THexString = ARRAY [0 .. 2 * MaxStrLength - 1] OF CHAR;
TCardIndexedFrom0To7 = ARRAY [0 .. 7] OF CARDINAL;
 
Line 2,784 ⟶ 3,283:
XorPlainText: TString = '';
ModPlainText: TString = '';
HexText: THexString;
Mode: TMode = iEncrypt;
HexText: TString;
 
(* ISAAC globals *)
(* external results *)
RandRsl: ARRAY [0 .. 256255] OF CARDINAL;
RandCnt: CARDINAL;
 
(* internal state *)
MM: ARRAY [0 .. 256255] OF CARDINAL;
AA: CARDINAL = 0;
BB: CARDINAL = 0;
Line 2,880 ⟶ 3,378:
PROCEDURE SeedIsaac(Seed: ARRAY OF CHAR; Flag: BOOLEAN);
VAR
I, MSeedLength: CARDINAL;
BEGIN
FOR I := 0 TO 255 DO
MM[I] := 0;
END;
MSeedLength := Length(Seed);
FOR I := 0 TO 255 DO
(* In case seed has less than 256 elements *)
IF I > MSeedLength THEN
RandRsl[I] := 0
ELSE
Line 2,941 ⟶ 3,439:
OrdMsgI: SHORTCARD;
BEGIN
Assign(''Msg, Destination);
FOR I := 0 TO Length(Msg) - 1 DO
OrdMsgI := ORD(Msg[I]);
Append(Destination[I] := CHR(GetRandomChar() BXOR OrdMsgI), Destination);
END;
END Vernam;
Line 2,977 ⟶ 3,475:
I: CARDINAL;
BEGIN
Assign(''Msg, Destination);
FOR I := 0 TO Length(Msg) - 1 DO
Append(Destination[I] := Caesar(M, Msg[I], GetRandomChar(), 95, ' '), Destination);
END;
END Vigenere;
Line 2,987 ⟶ 3,485:
SeedIsaac(Key, TRUE);
(* (2) Encryption *)
Mode := iEncrypt;
(* (a) XOR (Vernam) *)
Vernam(Msg, XorCipherText);
(* (b) MOD (Vigenere) *)
Vigenere(Msg, ModeiEncrypt, ModCipherText);
(* (3) Decryption *)
Mode := iDecrypt;
SeedIsaac(Key, TRUE);
(* (a) XOR (Vernam) *)
Vernam(XorCipherText, XorPlainText);
(* (b) MOD (Vigenere) *)
Vigenere(ModCipherText, ModeiDecrypt, ModPlainText);
(* program output *)
WriteString('Message: '); WriteString(Msg); WriteLn;
Line 3,009 ⟶ 3,505:
WriteString('MOD dcr: '); WriteString(ModPlainText); WriteLn;
END RosettaIsaac.
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 3,019 ⟶ 3,515:
MOD dcr: a Top Secret secret
</pre>
 
=={{header|Nim}}==
{{trans|Pascal}}
We choose the translate the Pascal version as the it’s easier to translate to Nim from Pascal rather than from C.
This is not an exact translation: the more important difference is the use of a global state record rather than a list of global variables. This global state is transmitted to each procedure. This way, it is possible to run several PRNG concurrently.
 
We also replaced the eight variables "a" to "h" with an array. This allows to simplify the code at several places by using a loop. And we changed the "mod" to "and", even if the compiler will likely optimize the modulo when the second operand is a power of two.
 
Note that the "mix" procedure could possibly be transformed in a template or be marked as "inline" (in the C version, it is a "define"). But as we are not in a procedure whose performance is critical, expanding the code rather than calling a procedure is not very useful.
 
<syntaxhighlight lang="nim">import strutils
 
type
 
IMode = enum iEncrypt, iDecrypt
 
State = object
# Internal.
mm: array[256, uint32]
aa, bb, cc: uint32
# External.
randrsl: array[256, uint32]
randcnt: uint32
 
 
proc isaac(s: var State) =
 
inc s.cc # "cc" just gets incremented once per 256 results
s.bb += s.cc # then combined with "bb".
 
for i in 0u32..255:
let x = s.mm[i]
case range[0..3](i and 3)
of 0: s.aa = s.aa xor s.aa shl 13
of 1: s.aa = s.aa xor s.aa shr 6
of 2: s.aa = s.aa xor s.aa shl 2
of 3: s.aa = s.aa xor s.aa shr 16
s.aa += s.mm[(i + 128) and 255]
let y = s.mm[(x shr 2) and 255] + s.aa + s.bb
s.mm[i] = y
s.bb = s.mm[(y shr 10) and 255] + x
s.randrsl[i] = s.bb
 
s.randcnt = 0
 
 
proc mix(a: var array[8, uint32]) =
a[0] = a[0] xor a[1] shl 11; a[3] += a[0]; a[1] += a[2]
a[1] = a[1] xor a[2] shr 2; a[4] += a[1]; a[2] += a[3]
a[2] = a[2] xor a[3] shl 8; a[5] += a[2]; a[3] += a[4]
a[3] = a[3] xor a[4] shr 16; a[6] += a[3]; a[4] += a[5]
a[4] = a[4] xor a[5] shl 10; a[7] += a[4]; a[5] += a[6]
a[5] = a[5] xor a[6] shr 4; a[0] += a[5]; a[6] += a[7]
a[6] = a[6] xor a[7] shl 8; a[1] += a[6]; a[7] += a[0]
a[7] = a[7] xor a[0] shr 9; a[2] += a[7]; a[0] += a[1]
 
 
proc iRandInit(s: var State; flag: bool) =
 
s.aa = 0; s.bb = 0; s.cc = 0
var a: array[8, uint32]
for item in a.mitems: item = 0x9e3779b9u32 # The golden ratio.
 
for i in 0..3: # Scramble it.
a.mix()
 
var i = 0u32
while true: # Fill in "mm" with messy stuff.
if flag:
# Use all the information in the seed.
for n in 0u32..7: a[n] += s.randrsl[n + i]
a.mix()
for n in 0u32..7: s.mm[n + i] = a[n]
inc i, 8
if i > 255: break
 
if flag:
# Do a second pass to make all of the seed affect all of "mm".
i = 0
while true:
for n in 0u32..7: a[n] += s.mm[n + i]
a.mix()
for n in 0u32..7: s.mm[n + i] = a[n]
inc i, 8
if i > 255: break
 
s.isaac() # Fill in the first set of results.
s.randcnt = 0 # Prepare to use the first set of results.
 
 
proc iSeed(s: var State; seed: string; flag: bool) =
## Seed ISAAC with a given string.
## The string can be any size. The first 256 values will be used.
s.mm.reset()
let m = seed.high
for i in 0..255:
s.randrsl[i] = if i > m: 0 else: ord(seed[i])
# Initialize ISAAC with seed.
s.iRandInit(flag)
 
 
proc iRandom(s: var State): uint32 =
## Get a random 32-bit value 0..int32.high.
result = s.randrsl[s.randcnt]
inc s.randcnt
if s.randcnt > 255:
s.isaac()
s.randcnt = 0
 
 
proc iRandA(s: var State): byte =
## Get a random character in printable ASCII range.
result = byte(s.iRandom() mod 95 + 32)
 
 
proc vernam(s: var State; msg: string): string =
## XOR encrypt on random stream. Output: ASCII string.
result.setLen(msg.len)
for i, c in msg:
result[i] = chr(s.irandA() xor byte(c))
 
 
template letterNum(letter, start: char): int =
ord(letter) - ord(start)
 
 
proc caesar(m: IMode; ch: char; shift, modulo: int; start: char): char =
let shift = if m == iEncrypt: shift else: -shift
var n = letterNum(ch, start) + shift
n = n mod modulo
if n < 0: inc n, modulo
result = chr(ord(start) + n)
 
 
proc vigenere(s: var State; msg: string; m: IMode): string =
## Vigenere MOD 95 encryption & decryption. Output: ASCII string.
result.setLen(msg.len)
for i, c in msg:
result[i] = caesar(m, c, s.iRanda().int, 95, ' ')
 
 
let
msg = "a Top Secret secret"
key = "this is my secret key"
 
var state: State
 
# 1) seed ISAAC with the key
state.iSeed(key, true)
# 2) Encryption
# a) XOR (Vernam)
let xctx = state.vernam(msg) # XOR ciphertext.
# b) MOD (Vigenere)
let mctx = state.vigenere(msg, iEncrypt) # MOD ciphertext.
# 3) Decryption
state.iSeed(key, true)
# a) XOR (Vernam)
let xptx = state.vernam(xctx) # XOR decryption (plaintext).
# b) MOD (Vigenere)
let mptx = state.vigenere(mctx, iDecrypt) # MOD decryption (plaintext).
# Program output
echo "Message: ", msg
echo " Key: ", key
echo " XOR: ", xctx.tohex
echo " MOD: ", mctx.toHex
echo "XOR dcr: ", xptx
echo "MOD dcr: ", mptx</syntaxhighlight>
 
{{out}}
<pre>Message: a Top Secret secret
Key: this is my secret key
XOR: 1C0636190B1260233B35125F1E1D0E2F4C5422
MOD: 734270227D36772A783B4F2A5F206266236978
XOR dcr: a Top Secret secret
MOD dcr: a Top Secret secret</pre>
 
=={{header|Pascal}}==
Free Pascal. A fully functional and complete reference solution of the task.
<syntaxhighlight lang="pascal">
<lang Pascal>
PROGRAM RosettaIsaac;
USES StrUtils;
StrUtils;
 
TYPE
iMode = (iEncrypt, iDecrypt);
 
TYPE iMode = (iEncrypt,iDecrypt);
// TASK globals
VAR
VAR msg : STRING = 'a Top Secret secret';
key msg : STRINGString = 'thisa isTop mySecret secret key';
xctx key : STRINGString = '';this //is XORmy ciphertextsecret key';
mctx xctx: STRINGString = ''; // MODXOR ciphertext
xptx mctx: STRINGString = ''; // XOR decryptionMOD (plaintext)ciphertext
mptx xptx: STRINGString = ''; // MODXOR decryption (plaintext)
mptx: String = ''; // MOD decryption (plaintext)
 
// ISAAC globals
VAR
// external results
// external results
VAR randrsl: ARRAY[0 .. 255] OF CARDINAL;
randrsl: ARRAY[0 .. 255] OF Cardinal;
randcnt: CARDINAL;
randcnt: Cardinal;
// internal state
VAR mm: ARRAY[0 .. 255] OF CARDINAL;
aa: CARDINAL = 0; bb: CARDINAL = 0; cc: CARDINAL = 0;
 
// internal state
mm: ARRAY[0 .. 255] OF Cardinal;
aa: Cardinal = 0;
bb: Cardinal = 0;
cc: Cardinal = 0;
 
PROCEDURE Isaac;
VAR
VAR i,x,y: CARDINAL;
i, x, y: Cardinal;
BEGIN
cc := cc + 1; // cc just gets incremented once per 256 results
bb := bb + cc; // then combined with bb
 
FOR i := 0 TO 255 DO BEGIN
BEGIN
x := mm[i];
x CASE:= (mm[i mod 4) OF];
0: aa := aa xorCASE (aai shlMOD 134); OF
1 0: aa := aa xorXOR (aa shrSHL 613);
2 1: aa := aa xorXOR (aa shlSHR 26);
3 2: aa := aa xorXOR (aa shrSHL 162);
3: aa := aa XOR (aa SHR 16);
END;
END;
aa := mm[(i+128) mod 256] + aa;
y aa := mm[(xi shr+ 2128) modMOD 256] + aa + bb;
y := mm[i(x SHR 2) MOD 256] :=+ yaa + bb;
bbmm[i] := mm[(y shr 10) mod 256] + x;
bb := mm[(y SHR 10) MOD 256] + x;
randrsl[i]:= bb;
randrsl[i] := bb;
END;
END;
// this reset was not in the original readable.c
randcnt := 0; // prepare to use the first set of results
END; {// Isaac}
 
PROCEDURE Mix(VAR a, b, c, d, e, f, g, h: Cardinal);
 
// if (flag==TRUE), then use the contents of randrsl[] to initialize mm[].
PROCEDURE mix(VAR a,b,c,d,e,f,g,h: CARDINAL);
BEGIN
a := a xorXOR b shlSHL 11; d := d + a; b := b + c;
b := b xorXOR c shrSHR 2; e := e + b; c := c + d;
c := c xorXOR d shlSHL 8; f := f + c; d := d + e;
d := d xorXOR e shrSHR 16; g := g + d; e := e + f;
e := e xorXOR f shlSHL 10; h := h + e; f := f + g;
f := f xorXOR g shrSHR 4; a := a + f; g := g + h;
g := g xorXOR h shlSHL 8; b := b + g; h := h + a;
h := h xorXOR a shrSHR 9; c := c + h; a := a + b;
END; {mix}// Mix
 
PROCEDURE iRandInit(flag: Boolean);
 
VAR
PROCEDURE iRandInit(flag: BOOLEAN);
VAR i, a, b, c, d, e, f, g, h: CARDINALCardinal;
BEGIN
aa := 0; bb := 0; cc := 0;
a := $9e3779b9; // the golden ratio
b := a; c := a; d := a; e := a; f := a; g := a; h := a;
b:=a; c:=a; d:=a; e:=a; f:=a; g:=a; h:=a;
 
FOR i := 0 TO 3 DO // scramble it
mixMix(a, b, c, d, e, f, g, h);
 
i := 0;
REPEAT // fill in mm[] with messy stuff
IF flag THEN
IF flag THEN BEGIN // use all the information in the seed
BEGIN // use all the information in the seed
a+=randrsl[i ]; b+=randrsl[i+1]; c+=randrsl[i+2]; d+=randrsl[i+3];
a e+= randrsl[i+4 ]; fb += randrsl[i+5]; g+=randrsl[i+6]; h+=randrsl[i+71];
c += randrsl[i + 2]; d += randrsl[i + 3];
e += randrsl[i + 4]; f += randrsl[i + 5];
g += randrsl[i + 6]; h += randrsl[i + 7];
END;
 
mixMix(a, b, c, d, e, f, g, h);
mm[i ] := a; mm[i + 1] := b; mm[i + 2] := c; mm[i + 3] := d;
mm[i + 4] := e; mm[i + 5] := f; mm[i + 6] := g; mm[i + 7] := h;
i += 8;
UNTIL i > 255;
 
IF (flag) THEN BEGIN
BEGIN
// do a second pass to make all of the seed affect all of mm
// do a second pass to make all of the seed affect all of mm
i:=0;
i REPEAT:= 0;
REPEAT
a+=mm[i ]; b+=mm[i+1]; c+=mm[i+2]; d+=mm[i+3];
ea += mm[i+4 ]; fb += mm[i +5 1]; gc += mm[i +6 2]; hd += mm[i +7 3];
e += mm[i + 4]; f += mm[i + 5]; g += mm[i + 6]; h += mm[i + 7];
mix(a,b,c,d,e,f,g,h);
mm[i ]:=Mix(a;, mm[i+1]:=b;, mm[i+2]:=c;, mm[i+3]:=d, e, f, g, h);
mm[i+4 ] :=e a; mm[i +5 1] :=f b; mm[i +6 2] :=g c; mm[i +7 3] :=h d;
mm[i + 4] := e; mm[i + 5] := f; mm[i + 6] := g; mm[i + 7] := h;
i+=8;
UNTIL i>255 += 8;
END UNTIL i > 255;
END;
isaac(); // fill in the first set of results
randcnt:=0Isaac(); // prepare tofill usein the first set of results
randcnt := 0; // prepare to use the first set of results
END; {randinit}
END; // iRandInit
 
// Seed ISAAC with a given string.
 
// The string can be any size. The first 256 values will be used.
{ Seed ISAAC with a given string.
PROCEDURE iSeed(seed: String; flag: Boolean);
The string can be any size. The first 256 values will be used.}
VAR
PROCEDURE iSeed(seed: STRING; flag: BOOLEAN);
VAR i, m: CARDINALCardinal;
BEGIN
FOR i := 0 TO 255 DO mm[i]:=0;
mm[i] := 0;
m := Length(seed)-1;
m := Length(seed) - 1;
FOR i:= 0 TO 255 DO BEGIN
FOR i := 0 TO 255 DO
// in case seed has less than 256 elements
BEGIN
IF i>m THEN randrsl[i]:=0
// in case seed has less than 256 elements
// Pascal strings are 1-based
IF i > m THEN
ELSE randrsl[i]:=ord(seed[i+1]);
randrsl[i] := 0
END;
// Pascal strings are 1-based
// initialize ISAAC with seed
ELSE
iRandInit(flag);
randrsl[i] := Ord(seed[i + 1]);
END; {iSeed}
END;
// initialize ISAAC with seed
iRandInit(flag);
END; // iSeed
 
// Get a random 32-bit value 0..MAXINT
 
FUNCTION iRandom: Cardinal;
{ Get a random 32-bit value 0..MAXINT }
FUNCTION iRandom : CARDINAL;
BEGIN
iRandom := randrsl[randcnt];
inc(randcnt);
IF (randcnt > 255) THEN BEGIN
BEGIN
Isaac();
Isaac;
randcnt := 0;
randcnt := 0;
END;
END; {iRandom}
END; // iRandom
 
// Get a random character in printable ASCII range
 
FUNCTION iRandA: Byte;
{ Get a random character in printable ASCII range }
FUNCTION iRandA: BYTE;
BEGIN
iRandA := iRandom modMOD 95 + 32;
END;
 
// Convert an ASCII string to a hexadecimal string
FUNCTION Ascii2Hex(s: String): String;
VAR
i: Cardinal;
BEGIN
Ascii2Hex := '';
FOR i := 1 TO Length(s) DO
Ascii2Hex += Dec2Numb(Ord(s[i]), 2, 16);
END; // Ascii2Hex
 
{// convertXOR anencrypt ASCIIon stringrandom tostream. aOutput: hexadecimalASCII string }
FUNCTION ascii2hexVernam(smsg: STRINGString): STRINGString;
VAR
VAR i: CARDINAL;
i: Cardinal;
BEGIN
BEGIN
ascii2hex := '';
Vernam := '';
FOR i := 1 TO Length(s) DO
FOR i := 1 to Length(msg) DO
ascii2hex += Dec2Numb(ord(s[i]),2,16);
Vernam += Chr(iRandA XOR Ord(msg[i]));
END;
END; // Vernam
 
// Get position of the letter in chosen alphabet
FUNCTION LetterNum(letter, start: Char): Byte;
BEGIN
LetterNum := (Ord(letter) - Ord(start));
END; // LetterNum
 
// Caesar-shift a character <shift> places: Generalized Vigenere
{ XOR encrypt on random stream. Output: ASCII string }
FUNCTION Caesar(m: iMode; ch: Char; shift, modulo: Integer; start: Char): Char;
FUNCTION Vernam(msg: STRING): STRING;
VAR
VAR i: CARDINAL;
n: Integer;
BEGIN
BEGIN
Vernam := '';
IF m = iDecrypt THEN
FOR i := 1 to length(msg) DO
shift := -shift;
Vernam += chr(iRandA xor ord(msg[i]));
n := LetterNum(ch, start) + shift;
END;
n := n MOD modulo;
 
IF n < 0 THEN
 
n += modulo;
{ Get position of the letter in chosen alphabet }
Caesar := Chr(Ord(start) + n);
FUNCTION letternum(letter, start: CHAR): byte;
END; // Caesar
BEGIN
letternum := (ord(letter)-ord(start));
END;
 
 
{ Caesar-shift a character <shift> places: Generalized Vigenere }
FUNCTION Caesar(m: iMode; ch: CHAR; shift, modulo: INTEGER; start: CHAR): CHAR;
VAR n: INTEGER;
BEGIN
IF m = iDecrypt THEN shift := -shift;
n := letternum(ch,start) + shift;
n := n MOD modulo;
IF n<0 THEN n += modulo;
Caesar := chr(ord(start)+n);
END;
 
 
{ Vigenere mod 95 encryption & decryption. Output: ASCII string }
FUNCTION Vigenere(msg: STRING; m: iMode): STRING;
VAR i: CARDINAL;
BEGIN
Vigenere := '';
FOR i := 1 to length(msg) DO
Vigenere += Caesar(m,msg[i],iRandA,95,' ');
END;
 
// Vigenere MOD 95 encryption & decryption. Output: ASCII string
FUNCTION Vigenere(msg: String; m: iMode): String;
VAR
i: Cardinal;
BEGIN
Vigenere := '';
FOR i := 1 to Length(msg) DO
Vigenere += Caesar(m, msg[i], iRandA, 95, ' ');
END; // Vigenere
 
BEGIN
// 1) seed ISAAC with the key
iSeed(key, true);
// 2) Encryption
// a) XOR (Vernam)
xctx := Vernam(msg);
// b) MOD (Vigenere)
mctx := Vigenere(msg, iEncrypt);
// 3) Decryption
iSeed(key, true);
// a) XOR (Vernam)
xptx := Vernam(xctx);
// b) MOD (Vigenere)
mptx := Vigenere(mctx, iDecrypt);
// program output
Writeln('Message: ', msg);
Writeln('Key : ', key);
Writeln('XOR : ',ascii2hex Ascii2Hex(xctx));
Writeln('MOD : ',ascii2hex Ascii2Hex(mctx));
Writeln('XOR dcr: ', xptx);
Writeln('MOD dcr: ', mptx);
END.
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 3,250 ⟶ 3,933:
as well as additional convenience functions.
 
<langsyntaxhighlight lang="perl">use warnings;
use strict;
use Math::Random::ISAAC;
Line 3,280 ⟶ 3,963:
map { ord($_) ^ shift(@iranda) } # xor it with rand char
split "", $msg; # Take each character
}</langsyntaxhighlight>
{{out}}
<pre>
Line 3,287 ⟶ 3,970:
XOR : 1C0636190B1260233B35125F1E1D0E2F4C5422
XOR dcr: a Top Secret secret
</pre>
 
=={{header|Perl 6}}==
<lang perl6>#!/usr/bin/env perl6
 
use v6.d;
 
my uint32 (@mm, @randrsl, $randcnt, $aa, $bb, $cc);
my \ϕ := 2654435769; constant MOD = 95; constant START = 32;
 
constant MAXINT = uint.Range.max;
enum CipherMode < ENCIPHER DECIPHER NONE >;
 
sub mix (\n) {
sub mix1 (\i, \v) {
n[i] +^= v;
n[(i+3)%8] += n[i];
n[(i+1)%8] += n[(i+2)%8];
}
mix1 0, n[1]+<11; mix1 1, n[2]+>2; mix1 2, n[3]+<8; mix1 3, n[4]+>16;
mix1 4, n[5]+<10; mix1 5, n[6]+>4; mix1 6, n[7]+<8; mix1 7, n[0]+>9 ;
}
 
sub randinit(\flag) {
$aa = $bb = $cc = 0;
my uint32 @n = [^8].map({ ϕ });
for ^4 { mix @n };
for 0,8 … 255 -> $i {
{ for (0..7) { @n[$^j] += @randrsl[$i + $^j] } } if flag;
mix @n;
for (0..7) { @mm[$i + $^j] = @n[$^j] }
}
if flag {
for 0,8 … 255 -> $i {
for ^8 { @n[$^j] += @mm[$i + $^j] };
mix @n;
for ^8 { @mm[$i + $^j] = @n[$^j] };
}
}
isaac;
$randcnt = 0;
}
 
sub isaac() {
$cc++;
$bb += $cc;
for ^256 -> $i {
my $x = @mm[$i];
given ($i % 4) {
when 0 { $aa +^= ($aa +< 13) }
when 1 { $aa +^= (($aa +& MAXINT) +> 6) }
when 2 { $aa +^= ($aa +< 2) }
when 3 { $aa +^= (($aa +& MAXINT) +> 16) }
}
$aa += @mm[($i + 128) % 256];
my $y = @mm[(($x +& MAXINT) +> 2) % 256] + $aa + $bb;
@mm[$i] = $y;
$bb = @mm[(($y +& MAXINT) +> 10) % 256] + $x;
@randrsl[$i] = $bb;
}
$randcnt = 0;
}
 
sub iRandom {
my $result = @randrsl[$randcnt++];
if ($randcnt > 255) {
isaac;
$randcnt = 0;
}
return $result;
}
 
sub iSeed(\seed, \flag) {
@mm = [^256].race.map({0});
my \m = seed.chars;
@randrsl = [^256].hyper.map({ $^i ≥ m ?? 0 !! seed.substr($^i,1).ord });
randinit(flag);
}
 
sub iRandA { return iRandom() % MOD + START };
 
sub vernam(\M) { ( map { (iRandA() +^ .ord ).chr }, M.comb ).join };
sub caesar(CipherMode \m, \ch, $shift is copy, \Modulo, \Start) {
$shift = -$shift if m == DECIPHER;
my $n = (ch.ord - Start) + $shift;
$n %= Modulo;
$n += Modulo if $n < 0;
return (Start + $n).chr;
}
 
sub caesarStr(CipherMode \m, \msg, \Modulo, \Start) {
my $sb = '';
for msg.comb {
$sb ~= caesar m, $^c, iRandA(), Modulo, Start;
}
return $sb;
}
multi MAIN () {
my \msg = "a Top Secret secret";
my \key = "this is my secret key";
iSeed key, True ;
my $vctx = vernam msg;
my $cctx = caesarStr ENCIPHER, msg, MOD, START;
 
iSeed key, True ;
my $vptx = vernam $vctx;
my $cptx = caesarStr DECIPHER, $cctx, MOD, START;
 
my $vctx2hex = ( map { .ord.fmt('%02X') }, $vctx.comb ).join('');
my $cctx2hex = ( map { .ord.fmt('%02X') }, $cctx.comb ).join('');
 
say "Message : ", msg;
say "Key : ", key;
say "XOR : ", $vctx2hex;
say "XOR dcr : ", $vptx;
say "MOD : ", $cctx2hex;
say "MOD dcr : ", $cptx;
}</lang>
{{out}}
<pre>
Message : a Top Secret secret
Key : this is my secret key
XOR : 1C0636190B1260233B35125F1E1D0E2F4C5422
XOR dcr : a Top Secret secret
MOD : 734270227D36772A783B4F2A5F206266236978
MOD dcr : a Top Secret secret
</pre>
 
Line 3,421 ⟶ 3,975:
{{trans|Pascal}}
We need the r32() function to convert our common sense maths into the needed unsigned_and_throw_away_any_high_bits maths.
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>-- demo\rosetta\ISAAC_Cipher.exw
<span style="color: #000080;font-style:italic;">--
 
-- demo\rosetta\ISAAC_Cipher.exw
sequence randrsl = repeat(0,256)
--</span>
integer randcnt
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
 
<span style="color: #004080;">sequence</span> <span style="color: #000000;">randrsl</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">256</span><span style="color: #0000FF;">)</span>
sequence mm
<span style="color: #004080;">integer</span> <span style="color: #000000;">randcnt</span>
atom aa,bb,cc
<span style="color: #004080;">sequence</span> <span style="color: #000000;">mm</span>
function r32(object a)
<span style="color: #004080;">atom</span> <span style="color: #000000;">aa</span><span style="color: #0000FF;">,</span><span style="color: #000000;">bb</span><span style="color: #0000FF;">,</span><span style="color: #000000;">cc</span>
if sequence(a) then
for i=1 to length(a) do
<span style="color: #008080;">function</span> <span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #004080;">object</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">)</span>
a[i] = r32(a[i])
<span style="color: #008080;">if</span> <span style="color: #004080;">sequence</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
end for
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
return a
<span style="color: #000000;">a</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
if a<0 then a+=#100000000 end if
<span style="color: #008080;">return</span> <span style="color: #000000;">a</span>
return remainder(a,#100000000)
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end function
<span style="color: #008080;">if</span> <span style="color: #000000;">a</span><span style="color: #0000FF;"><</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">+=</span><span style="color: #000000;">#100000000</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
 
<span style="color: #008080;">return</span> <span style="color: #7060A8;">remainder</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">#100000000</span><span style="color: #0000FF;">)</span>
function shl(atom word, integer bits)
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
return r32(word*power(2,bits))
end function
 
function shr(atom v, integer bits)
return floor(v/power(2,bits))
end function
 
procedure Isaac()
cc += 1; -- cc just gets incremented once per 256 results
bb += cc; -- then combined with bb
for i=1 to 256 do
atom x = mm[i]
switch mod(i-1,4) do
case 0: aa := xor_bits(aa,shl(aa,13))
case 1: aa := xor_bits(aa,shr(aa, 6))
case 2: aa := xor_bits(aa,shl(aa, 2))
case 3: aa := xor_bits(aa,shr(aa,16))
end switch
aa = r32(mm[xor_bits(i-1,#80)+1]+aa)
atom y := mm[and_bits(shr(x,2),#FF)+1]+aa+bb
mm[i] := y;
bb := r32(mm[and_bits(shr(y,10),#FF)+1] + x)
randrsl[i]:= bb;
end for
randcnt = 1
end procedure
<span style="color: #008080;">function</span> <span style="color: #000000;">shl</span><span style="color: #0000FF;">(</span><span style="color: #004080;">atom</span> <span style="color: #000000;">word</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">bits</span><span style="color: #0000FF;">)</span>
function mix(sequence a8)
<span style="color: #008080;">return</span> <span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">word</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">bits</span><span style="color: #0000FF;">))</span>
atom {a,b,c,d,e,f,g,h} = a8
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
a = xor_bits(a,shl(b,11)); {d,b} = r32({d+a,b+c});
b = xor_bits(b,shr(c, 2)); {e,c} = r32({e+b,c+d});
c = xor_bits(c,shl(d, 8)); {f,d} = r32({f+c,d+e});
d = xor_bits(d,shr(e,16)); {g,e} = r32({g+d,e+f});
e = xor_bits(e,shl(f,10)); {h,f} = r32({h+e,f+g});
f = xor_bits(f,shr(g, 4)); {a,g} = r32({a+f,g+h});
g = xor_bits(g,shl(h, 8)); {b,h} = r32({b+g,h+a});
h = xor_bits(h,shr(a, 9)); {c,a} = r32({c+h,a+b});
a8 = {a,b,c,d,e,f,g,h}
return a8
end function
 
procedure iRandInit()
{aa,bb,cc} = {0,0,0}
sequence a8 = repeat(#9e3779b9,8) -- the golden ratio
for i=1 to 4 do -- scramble it
a8 = mix(a8)
end for
for i=1 to 255 by 8 do
a8 = mix(sq_add(a8,randrsl[i..i+7]))
mm[i..i+7] = a8
end for
for i=1 to 255 by 8 do
a8 = mix(r32(sq_add(a8,mm[i..i+7])))
mm[i..i+7] = a8
end for
Isaac() -- fill in the first set of results
end procedure
<span style="color: #008080;">function</span> <span style="color: #000000;">shr</span><span style="color: #0000FF;">(</span><span style="color: #004080;">atom</span> <span style="color: #000000;">v</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">bits</span><span style="color: #0000FF;">)</span>
procedure iSeed(string seed)
<span style="color: #008080;">return</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">v</span><span style="color: #0000FF;">/</span><span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">bits</span><span style="color: #0000FF;">))</span>
mm = repeat(0,256)
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
randrsl = repeat(0,256)
randrsl[1..min(length(seed),256)] = seed
iRandInit()
end procedure
<span style="color: #008080;">procedure</span> <span style="color: #000000;">Isaac</span><span style="color: #0000FF;">()</span>
function randch()
<span style="color: #000000;">cc</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">;</span> <span style="color: #000080;font-style:italic;">-- cc just gets incremented once per 256 results </span>
atom res = mod(randrsl[randcnt],95)+32
<span style="color: #000000;">bb</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">cc</span><span style="color: #0000FF;">;</span> <span style="color: #000080;font-style:italic;">-- then combined with bb </span>
randcnt += 1
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">256</span> <span style="color: #008080;">do</span>
if randcnt>256 then
<span style="color: #004080;">atom</span> <span style="color: #000000;">x</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">mm</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
Isaac()
<span style="color: #008080;">switch</span> <span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
end if
<span style="color: #008080;">case</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">:</span> <span style="color: #000000;">aa</span> <span style="color: #0000FF;">:=</span> <span style="color: #7060A8;">xor_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">aa</span><span style="color: #0000FF;">,</span><span style="color: #000000;">shl</span><span style="color: #0000FF;">(</span><span style="color: #000000;">aa</span><span style="color: #0000FF;">,</span><span style="color: #000000;">13</span><span style="color: #0000FF;">))</span>
return res
<span style="color: #008080;">case</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">:</span> <span style="color: #000000;">aa</span> <span style="color: #0000FF;">:=</span> <span style="color: #7060A8;">xor_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">aa</span><span style="color: #0000FF;">,</span><span style="color: #000000;">shr</span><span style="color: #0000FF;">(</span><span style="color: #000000;">aa</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">6</span><span style="color: #0000FF;">))</span>
end function
<span style="color: #008080;">case</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">:</span> <span style="color: #000000;">aa</span> <span style="color: #0000FF;">:=</span> <span style="color: #7060A8;">xor_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">aa</span><span style="color: #0000FF;">,</span><span style="color: #000000;">shl</span><span style="color: #0000FF;">(</span><span style="color: #000000;">aa</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">case</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">:</span> <span style="color: #000000;">aa</span> <span style="color: #0000FF;">:=</span> <span style="color: #7060A8;">xor_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">aa</span><span style="color: #0000FF;">,</span><span style="color: #000000;">shr</span><span style="color: #0000FF;">(</span><span style="color: #000000;">aa</span><span style="color: #0000FF;">,</span><span style="color: #000000;">16</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">switch</span>
<span style="color: #000000;">aa</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">mm</span><span style="color: #0000FF;">[</span><span style="color: #7060A8;">xor_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">#80</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]+</span><span style="color: #000000;">aa</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">y</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">mm</span><span style="color: #0000FF;">[</span><span style="color: #7060A8;">and_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">shr</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">),</span><span style="color: #000000;">#FF</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]+</span><span style="color: #000000;">aa</span><span style="color: #0000FF;">+</span><span style="color: #000000;">bb</span>
<span style="color: #000000;">mm</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">;</span>
<span style="color: #000000;">bb</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">mm</span><span style="color: #0000FF;">[</span><span style="color: #7060A8;">and_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">shr</span><span style="color: #0000FF;">(</span><span style="color: #000000;">y</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">),</span><span style="color: #000000;">#FF</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">randrsl</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]:=</span> <span style="color: #000000;">bb</span><span style="color: #0000FF;">;</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #000000;">randcnt</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">mix</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">a8</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">atom</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">c</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">,</span><span style="color: #000000;">e</span><span style="color: #0000FF;">,</span><span style="color: #000000;">f</span><span style="color: #0000FF;">,</span><span style="color: #000000;">g</span><span style="color: #0000FF;">,</span><span style="color: #000000;">h</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">a8</span>
<span style="color: #000000;">a</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">xor_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">shl</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">11</span><span style="color: #0000FF;">));</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">d</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r32</span><span style="color: #0000FF;">({</span><span style="color: #000000;">d</span><span style="color: #0000FF;">+</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b</span><span style="color: #0000FF;">+</span><span style="color: #000000;">c</span><span style="color: #0000FF;">});</span>
<span style="color: #000000;">b</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">xor_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">shr</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">));</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">e</span><span style="color: #0000FF;">,</span><span style="color: #000000;">c</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r32</span><span style="color: #0000FF;">({</span><span style="color: #000000;">e</span><span style="color: #0000FF;">+</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">c</span><span style="color: #0000FF;">+</span><span style="color: #000000;">d</span><span style="color: #0000FF;">});</span>
<span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">xor_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">,</span><span style="color: #000000;">shl</span><span style="color: #0000FF;">(</span><span style="color: #000000;">d</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">8</span><span style="color: #0000FF;">));</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">f</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r32</span><span style="color: #0000FF;">({</span><span style="color: #000000;">f</span><span style="color: #0000FF;">+</span><span style="color: #000000;">c</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">+</span><span style="color: #000000;">e</span><span style="color: #0000FF;">});</span>
<span style="color: #000000;">d</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">xor_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">d</span><span style="color: #0000FF;">,</span><span style="color: #000000;">shr</span><span style="color: #0000FF;">(</span><span style="color: #000000;">e</span><span style="color: #0000FF;">,</span><span style="color: #000000;">16</span><span style="color: #0000FF;">));</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">g</span><span style="color: #0000FF;">,</span><span style="color: #000000;">e</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r32</span><span style="color: #0000FF;">({</span><span style="color: #000000;">g</span><span style="color: #0000FF;">+</span><span style="color: #000000;">d</span><span style="color: #0000FF;">,</span><span style="color: #000000;">e</span><span style="color: #0000FF;">+</span><span style="color: #000000;">f</span><span style="color: #0000FF;">});</span>
<span style="color: #000000;">e</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">xor_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">e</span><span style="color: #0000FF;">,</span><span style="color: #000000;">shl</span><span style="color: #0000FF;">(</span><span style="color: #000000;">f</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">));</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">h</span><span style="color: #0000FF;">,</span><span style="color: #000000;">f</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r32</span><span style="color: #0000FF;">({</span><span style="color: #000000;">h</span><span style="color: #0000FF;">+</span><span style="color: #000000;">e</span><span style="color: #0000FF;">,</span><span style="color: #000000;">f</span><span style="color: #0000FF;">+</span><span style="color: #000000;">g</span><span style="color: #0000FF;">});</span>
<span style="color: #000000;">f</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">xor_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">f</span><span style="color: #0000FF;">,</span><span style="color: #000000;">shr</span><span style="color: #0000FF;">(</span><span style="color: #000000;">g</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">));</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">g</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r32</span><span style="color: #0000FF;">({</span><span style="color: #000000;">a</span><span style="color: #0000FF;">+</span><span style="color: #000000;">f</span><span style="color: #0000FF;">,</span><span style="color: #000000;">g</span><span style="color: #0000FF;">+</span><span style="color: #000000;">h</span><span style="color: #0000FF;">});</span>
<span style="color: #000000;">g</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">xor_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">g</span><span style="color: #0000FF;">,</span><span style="color: #000000;">shl</span><span style="color: #0000FF;">(</span><span style="color: #000000;">h</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">8</span><span style="color: #0000FF;">));</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">h</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r32</span><span style="color: #0000FF;">({</span><span style="color: #000000;">b</span><span style="color: #0000FF;">+</span><span style="color: #000000;">g</span><span style="color: #0000FF;">,</span><span style="color: #000000;">h</span><span style="color: #0000FF;">+</span><span style="color: #000000;">a</span><span style="color: #0000FF;">});</span>
<span style="color: #000000;">h</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">xor_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">h</span><span style="color: #0000FF;">,</span><span style="color: #000000;">shr</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9</span><span style="color: #0000FF;">));</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">c</span><span style="color: #0000FF;">,</span><span style="color: #000000;">a</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r32</span><span style="color: #0000FF;">({</span><span style="color: #000000;">c</span><span style="color: #0000FF;">+</span><span style="color: #000000;">h</span><span style="color: #0000FF;">,</span><span style="color: #000000;">a</span><span style="color: #0000FF;">+</span><span style="color: #000000;">b</span><span style="color: #0000FF;">});</span>
<span style="color: #000000;">a8</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">c</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">,</span><span style="color: #000000;">e</span><span style="color: #0000FF;">,</span><span style="color: #000000;">f</span><span style="color: #0000FF;">,</span><span style="color: #000000;">g</span><span style="color: #0000FF;">,</span><span style="color: #000000;">h</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">a8</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">iRandInit</span><span style="color: #0000FF;">()</span>
function Vernam(string msg)
<span style="color: #0000FF;">{</span><span style="color: #000000;">aa</span><span style="color: #0000FF;">,</span><span style="color: #000000;">bb</span><span style="color: #0000FF;">,</span><span style="color: #000000;">cc</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">}</span>
string res = ""
<span style="color: #004080;">sequence</span> <span style="color: #000000;">a8</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">#9e3779b9</span><span style="color: #0000FF;">,</span><span style="color: #000000;">8</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- the golden ratio</span>
for i=1 to length(msg) do
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">4</span> <span style="color: #008080;">do</span> <span style="color: #000080;font-style:italic;">-- scramble it </span>
res &= xor_bits(msg[i],randch())
<span style="color: #000000;">a8</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">mix</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a8</span><span style="color: #0000FF;">)</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
return res
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">255</span> <span style="color: #008080;">by</span> <span style="color: #000000;">8</span> <span style="color: #008080;">do</span>
end function
<span style="color: #000000;">a8</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">mix</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">sq_add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a8</span><span style="color: #0000FF;">,</span><span style="color: #000000;">randrsl</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">..</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">7</span><span style="color: #0000FF;">]))</span>
 
<span style="color: #000000;">mm</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">..</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">7</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">a8</span>
function Caesar(integer ch, shift)
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
return ' '+mod(ch-' '+shift,95)
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">255</span> <span style="color: #008080;">by</span> <span style="color: #000000;">8</span> <span style="color: #008080;">do</span>
end function
<span style="color: #000000;">a8</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">mix</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">sq_add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a8</span><span style="color: #0000FF;">,</span><span style="color: #000000;">mm</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">..</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">7</span><span style="color: #0000FF;">])))</span>
<span style="color: #000000;">mm</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">..</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">7</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">a8</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #000000;">Isaac</span><span style="color: #0000FF;">()</span> <span style="color: #000080;font-style:italic;">-- fill in the first set of results </span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">iSeed</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">seed</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">mm</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">256</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">randrsl</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">256</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">randrsl</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #7060A8;">min</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">seed</span><span style="color: #0000FF;">),</span><span style="color: #000000;">256</span><span style="color: #0000FF;">)]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">seed</span>
<span style="color: #000000;">iRandInit</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">randch</span><span style="color: #0000FF;">()</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">randrsl</span><span style="color: #0000FF;">[</span><span style="color: #000000;">randcnt</span><span style="color: #0000FF;">],</span><span style="color: #000000;">95</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">32</span>
<span style="color: #000000;">randcnt</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">randcnt</span><span style="color: #0000FF;">></span><span style="color: #000000;">256</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">Isaac</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">Vernam</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">msg</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">msg</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #7060A8;">xor_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">msg</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">randch</span><span style="color: #0000FF;">())</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">Caesar</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">shift</span><span style="color: #0000FF;">)</span>
enum ENCRYPT = +1,
<span style="color: #008080;">return</span> <span style="color: #008000;">' '</span><span style="color: #0000FF;">+</span><span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">-</span><span style="color: #008000;">' '</span><span style="color: #0000FF;">+</span><span style="color: #000000;">shift</span><span style="color: #0000FF;">,</span><span style="color: #000000;">95</span><span style="color: #0000FF;">)</span>
DECRYPT = -1
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
 
function Vigenere(string msg, integer mode)
<span style="color: #008080;">enum</span> <span style="color: #000000;">ENCRYPT</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span>
string res = ""
<span style="color: #000000;">DECRYPT</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span>
for i=1 to length(msg) do
res &= Caesar(msg[i],randch()*mode)
end for
return res
end function
<span style="color: #008080;">function</span> <span style="color: #000000;">Vigenere</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">msg</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">mode</span><span style="color: #0000FF;">)</span>
constant string msg = "a Top Secret secret",
<span style="color: #004080;">string</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span>
key = "this is my secret key"
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">msg</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
 
<span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">Caesar</span><span style="color: #0000FF;">(</span><span style="color: #000000;">msg</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">randch</span><span style="color: #0000FF;">()*</span><span style="color: #000000;">mode</span><span style="color: #0000FF;">)</span>
iSeed(key)
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
string xctx := Vernam(msg),
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
mctx := Vigenere(msg,ENCRYPT)
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
 
iSeed(key)
<span style="color: #008080;">constant</span> <span style="color: #004080;">string</span> <span style="color: #000000;">msg</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"a Top Secret secret"</span><span style="color: #0000FF;">,</span>
string xptx := Vernam(xctx),
<span style="color: #000000;">key</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"this is my secret key"</span>
mptx := Vigenere(mctx,DECRYPT)
 
<span style="color: #000000;">iSeed</span><span style="color: #0000FF;">(</span><span style="color: #000000;">key</span><span style="color: #0000FF;">)</span>
function ascii2hex(string s)
<span style="color: #004080;">string</span> <span style="color: #000000;">xctx</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">Vernam</span><span style="color: #0000FF;">(</span><span style="color: #000000;">msg</span><span style="color: #0000FF;">),</span>
string res = ""
<span style="color: #000000;">mctx</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">Vigenere</span><span style="color: #0000FF;">(</span><span style="color: #000000;">msg</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ENCRYPT</span><span style="color: #0000FF;">)</span>
for i=1 to length(s) do
res &= sprintf("%02x",s[i])
<span style="color: #000000;">iSeed</span><span style="color: #0000FF;">(</span><span style="color: #000000;">key</span><span style="color: #0000FF;">)</span>
end for
<span style="color: #004080;">string</span> <span style="color: #000000;">xptx</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">Vernam</span><span style="color: #0000FF;">(</span><span style="color: #000000;">xctx</span><span style="color: #0000FF;">),</span>
return res
<span style="color: #000000;">mptx</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">Vigenere</span><span style="color: #0000FF;">(</span><span style="color: #000000;">mctx</span><span style="color: #0000FF;">,</span><span style="color: #000000;">DECRYPT</span><span style="color: #0000FF;">)</span>
end function
 
<span style="color: #008080;">function</span> <span style="color: #000000;">ascii2hex</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
printf(1,"Message: %s\n",{msg})
<span style="color: #004080;">string</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span>
printf(1,"Key : %s\n",{key})
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
printf(1,"XOR : %s\n",{ascii2hex(xctx)})
<span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%02x"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span>
printf(1,"MOD : %s\n",{ascii2hex(mctx)})
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
printf(1,"XOR dcr: %s\n",{xptx})
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
printf(1,"MOD dcr: %s\n",{mptx})</lang>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Message: %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">msg</span><span style="color: #0000FF;">})</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Key : %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">key</span><span style="color: #0000FF;">})</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"XOR : %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">ascii2hex</span><span style="color: #0000FF;">(</span><span style="color: #000000;">xctx</span><span style="color: #0000FF;">)})</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"MOD : %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">ascii2hex</span><span style="color: #0000FF;">(</span><span style="color: #000000;">mctx</span><span style="color: #0000FF;">)})</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"XOR dcr: %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">xptx</span><span style="color: #0000FF;">})</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"MOD dcr: %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">mptx</span><span style="color: #0000FF;">})</span>
<span style="color: #0000FF;">?</span><span style="color: #008000;">"done"</span>
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">wait_key</span><span style="color: #0000FF;">()</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 3,574 ⟶ 4,135:
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(de add32 @
(mod32 (pass +)) )
 
Line 3,678 ⟶ 4,239:
95 ) ) ) ) ) ) ) ) ) )
 
(bye)</langsyntaxhighlight>
 
=={{header|Python}}==
Line 3,688 ⟶ 4,249:
This implementation extends the Random class of the built-in random module, so it automatically inherits methods for generating several distributions, as well as support for shuffling and sampling collections.
 
<langsyntaxhighlight Pythonlang="python">import random
import collections
 
Line 3,884 ⟶ 4,445:
print('MOD :', hexify(caesar_encoded))
print('MOD dcr:', caesar_decoded)
</syntaxhighlight>
</lang>
 
=={{header|Racket}}==
Line 3,896 ⟶ 4,457:
left from after the XOR, and one with a cleanly reseeded state engine.
 
<langsyntaxhighlight lang="racket">#lang racket
;; Imperative version: Translation of C
;; Vigenère: Translation of Pascal
Line 4,150 ⟶ 4,711:
(randctx-b C) => #x902c0691
(randctx-c C) => 10))
}</langsyntaxhighlight>
 
{{out}}
Line 4,168 ⟶ 4,729:
< context reseeded
Vigenère (-MOD): [6120546f702053656372657420736563726574 "a Top Secret secret"]</pre>
 
=={{header|Raku}}==
(formerly Perl 6)
<syntaxhighlight lang="raku" line>my uint32 (@mm, @randrsl, $randcnt, $aa, $bb, $cc);
my \ϕ := 2654435769; constant MOD = 95; constant START = 32;
 
constant MAXINT = uint.Range.max;
enum CipherMode < ENCIPHER DECIPHER NONE >;
 
sub mix (\n) {
sub mix1 (\i, \v) {
n[i] +^= v;
n[(i+3)%8] += n[i];
n[(i+1)%8] += n[(i+2)%8];
}
mix1 0, n[1]+<11; mix1 1, n[2]+>2; mix1 2, n[3]+<8; mix1 3, n[4]+>16;
mix1 4, n[5]+<10; mix1 5, n[6]+>4; mix1 6, n[7]+<8; mix1 7, n[0]+>9 ;
}
 
sub randinit(\flag) {
$aa = $bb = $cc = 0;
my uint32 @n = [^8].map({ ϕ });
for ^4 { mix @n };
for 0,8 … 255 -> $i {
{ for (0..7) { @n[$^j] += @randrsl[$i + $^j] } } if flag;
mix @n;
for (0..7) { @mm[$i + $^j] = @n[$^j] }
}
if flag {
for 0,8 … 255 -> $i {
for ^8 { @n[$^j] += @mm[$i + $^j] };
mix @n;
for ^8 { @mm[$i + $^j] = @n[$^j] };
}
}
isaac;
$randcnt = 0;
}
 
sub isaac() {
$cc++;
$bb += $cc;
for ^256 -> $i {
my $x = @mm[$i];
given ($i % 4) {
when 0 { $aa +^= ($aa +< 13) }
when 1 { $aa +^= (($aa +& MAXINT) +> 6) }
when 2 { $aa +^= ($aa +< 2) }
when 3 { $aa +^= (($aa +& MAXINT) +> 16) }
}
$aa += @mm[($i + 128) % 256];
my $y = @mm[(($x +& MAXINT) +> 2) % 256] + $aa + $bb;
@mm[$i] = $y;
$bb = @mm[(($y +& MAXINT) +> 10) % 256] + $x;
@randrsl[$i] = $bb;
}
$randcnt = 0;
}
 
sub iRandom {
my $result = @randrsl[$randcnt++];
if ($randcnt > 255) {
isaac;
$randcnt = 0;
}
return $result;
}
 
sub iSeed(\seed, \flag) {
@mm = [^256].race.map({0});
my \m = seed.chars;
@randrsl = [^256].hyper.map({ $^i ≥ m ?? 0 !! seed.substr($^i,1).ord });
randinit(flag);
}
 
sub iRandA { return iRandom() % MOD + START };
 
sub vernam(\M) { ( map { (iRandA() +^ .ord ).chr }, M.comb ).join };
sub caesar(CipherMode \m, \ch, $shift is copy, \Modulo, \Start) {
$shift = -$shift if m == DECIPHER;
my $n = (ch.ord - Start) + $shift;
$n %= Modulo;
$n += Modulo if $n < 0;
return (Start + $n).chr;
}
 
sub caesarStr(CipherMode \m, \msg, \Modulo, \Start) {
my $sb = '';
for msg.comb {
$sb ~= caesar m, $^c, iRandA(), Modulo, Start;
}
return $sb;
}
multi MAIN () {
my \msg = "a Top Secret secret";
my \key = "this is my secret key";
iSeed key, True ;
my $vctx = vernam msg;
my $cctx = caesarStr ENCIPHER, msg, MOD, START;
 
iSeed key, True ;
my $vptx = vernam $vctx;
my $cptx = caesarStr DECIPHER, $cctx, MOD, START;
 
my $vctx2hex = ( map { .ord.fmt('%02X') }, $vctx.comb ).join('');
my $cctx2hex = ( map { .ord.fmt('%02X') }, $cctx.comb ).join('');
 
say "Message : ", msg;
say "Key : ", key;
say "XOR : ", $vctx2hex;
say "XOR dcr : ", $vptx;
say "MOD : ", $cctx2hex;
say "MOD dcr : ", $cptx;
}</syntaxhighlight>
{{out}}
<pre>
Message : a Top Secret secret
Key : this is my secret key
XOR : 1C0636190B1260233B35125F1E1D0E2F4C5422
XOR dcr : a Top Secret secret
MOD : 734270227D36772A783B4F2A5F206266236978
MOD dcr : a Top Secret secret
</pre>
 
=={{header|REXX}}==
===version 1===
<langsyntaxhighlight lang="rexx">/* REXX ---------------------------------------------------------------
* 24.07.2014 Walter Pachl translated from Pascal
* extend with decryption (following Pascal)
Line 4,378 ⟶ 5,065:
If arg(3)<>'' Then
res=res+arg(3)
return res//4294967296</langsyntaxhighlight>
{{out}}
<pre>Message: a Top Secret secret
Line 4,389 ⟶ 5,076:
===version 2===
This can be used to encrypt a file and thereafter decrypt it.
<langsyntaxhighlight lang="rexx">/* REXX ---------------------------------------------------------------
* 25.07.2014 Walter Pachl framing version 1 for processing a file
*--------------------------------------------------------------------*/
Line 4,627 ⟶ 5,314:
parse Arg fid
Parse Var fid fn '.' ft
Return fn</langsyntaxhighlight>
{{out}}
<pre>Please enter a key
Line 4,639 ⟶ 5,326:
This is a little test file
that shows my encryption</pre>
 
=={{header|Rust}}==
<syntaxhighlight lang="rust">
//! includes the XOR version of the encryption scheme
 
use std::num::Wrapping as w;
 
const MSG: &str = "a Top Secret secret";
const KEY: &str = "this is my secret key";
 
fn main() {
let mut isaac = Isaac::new();
isaac.seed(KEY, true);
let encr = isaac.vernam(MSG.as_bytes());
 
println!("msg: {}", MSG);
println!("key: {}", KEY);
print!("XOR: ");
for a in &encr {
print!("{:02X}", *a);
}
 
let mut isaac = Isaac::new();
isaac.seed(KEY, true);
let decr = isaac.vernam(&encr[..]);
 
print!("\nXOR dcr: ");
println!("{}", String::from_utf8(decr).unwrap())
}
 
macro_rules! mix_v(
($a:expr) => (
{
$a[0] ^= $a[1] << 11; $a[3] += $a[0]; $a[1] += $a[2];
$a[1] ^= $a[2] >> 2; $a[4] += $a[1]; $a[2] += $a[3];
$a[2] ^= $a[3] << 8; $a[5] += $a[2]; $a[3] += $a[4];
$a[3] ^= $a[4] >> 16; $a[6] += $a[3]; $a[4] += $a[5];
$a[4] ^= $a[5] << 10; $a[7] += $a[4]; $a[5] += $a[6];
$a[5] ^= $a[6] >> 4; $a[0] += $a[5]; $a[6] += $a[7];
$a[6] ^= $a[7] << 8; $a[1] += $a[6]; $a[7] += $a[0];
$a[7] ^= $a[0] >> 9; $a[2] += $a[7]; $a[0] += $a[1];
} );
);
 
struct Isaac {
mm: [w<u32>; 256],
aa: w<u32>,
bb: w<u32>,
cc: w<u32>,
rand_rsl: [w<u32>; 256],
rand_cnt: u32,
}
 
impl Isaac {
fn new() -> Isaac {
Isaac {
mm: [w(0u32); 256],
aa: w(0),
bb: w(0),
cc: w(0),
rand_rsl: [w(0u32); 256],
rand_cnt: 0,
}
}
 
fn isaac(&mut self) {
self.cc += w(1);
self.bb += self.cc;
 
for i in 0..256 {
let w(x) = self.mm[i];
match i % 4 {
0 => self.aa ^= self.aa << 13,
1 => self.aa ^= self.aa >> 6,
2 => self.aa ^= self.aa << 2,
3 => self.aa ^= self.aa >> 16,
_ => unreachable!(),
}
 
self.aa += self.mm[((i + 128) % 256) as usize];
let w(y) = self.mm[((x >> 2) % 256) as usize] + self.aa + self.bb;
self.bb = self.mm[((y >> 10) % 256) as usize] + w(x);
self.rand_rsl[i] = self.bb;
}
 
self.rand_cnt = 0;
}
 
fn rand_init(&mut self, flag: bool) {
let mut a_v = [w(0x9e37_79b9u32); 8];
 
for _ in 0..4 {
// scramble it
mix_v!(a_v);
}
 
for i in (0..256).step_by(8) {
// fill in mm[] with messy stuff
if flag {
// use all the information in the seed
for (j, value) in a_v.iter_mut().enumerate().take(8) {
*value += self.rand_rsl[i + j];
}
}
mix_v!(a_v);
for (j, value) in a_v.iter().enumerate().take(8) {
self.mm[i + j] = *value;
}
}
 
if flag {
// do a second pass to make all of the seed affect all of mm
for i in (0..256).step_by(8) {
for (j, value) in a_v.iter_mut().enumerate().take(8) {
*value += self.mm[i + j];
}
mix_v!(a_v);
for (j, value) in a_v.iter().enumerate().take(8) {
self.mm[i + j] = *value;
}
}
}
 
self.isaac(); // fill in the first set of results
self.rand_cnt = 0; // prepare to use the first set of results
}
 
/// Get a random 32-bit value
fn i_random(&mut self) -> u32 {
let r = self.rand_rsl[self.rand_cnt as usize];
self.rand_cnt += 1;
if self.rand_cnt > 255 {
self.isaac();
self.rand_cnt = 0;
}
r.0
}
 
/// Seed ISAAC with a string
fn seed(&mut self, seed: &str, flag: bool) {
for i in 0..256 {
self.mm[i] = w(0);
}
for i in 0..256 {
self.rand_rsl[i] = w(0);
}
 
for i in 0..seed.len() {
self.rand_rsl[i] = w(u32::from(seed.as_bytes()[i]));
}
// initialize ISAAC with seed
self.rand_init(flag);
}
 
/// Get a random character in printable ASCII range
fn i_rand_ascii(&mut self) -> u8 {
(self.i_random() % 95 + 32) as u8
}
 
/// XOR message
fn vernam(&mut self, msg: &[u8]) -> Vec<u8> {
msg.iter()
.map(|&b| (self.i_rand_ascii() ^ b))
.collect::<Vec<u8>>()
}
}
 
impl Default for Isaac {
fn default() -> Self {
Isaac::new()
}
}
 
</syntaxhighlight>
{{out}}
<pre>
msg: a Top Secret secret
key: this is my secret key
XOR: 1C0636190B1260233B35125F1E1D0E2F4C5422
XOR dcr: a Top Secret secret
</pre>
 
=={{header|Sidef}}==
{{trans|Perl}}
<langsyntaxhighlight lang="ruby">require('Math::Random::ISAAC')
 
func xor_isaac(key, msg) {
Line 4,661 ⟶ 5,529:
say "Key : #{key}"
say "XOR : #{enc}"
say "XOR dcr: #{pack('H*', dec)}"</langsyntaxhighlight>
{{out}}
<pre>
Line 4,673 ⟶ 5,541:
{{works with|Tcl|8.6}}
{{trans|Go}}
<langsyntaxhighlight lang="tcl">package require Tcl 8.6
 
oo::class create ISAAC {
Line 4,782 ⟶ 5,650:
return [binary encode hex [binary format c* $b]]
}
}</langsyntaxhighlight>
Demonstrating:
<langsyntaxhighlight lang="tcl">set key "this is my secret key"
set msg "a Top Secret secret"
ISAAC create demo $key
puts "Message: $msg"
puts "Key : $key"
puts "XOR : [demo vernam $msg]"</langsyntaxhighlight>
{{out}}
<pre>
Line 4,795 ⟶ 5,663:
Key : this is my secret key
XOR : 1c0636190b1260233b35125f1e1d0e2f4c5422
</pre>
 
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|Wren-iterate}}
{{libheader|Wren-dynamic}}
{{libheader|Wren-fmt}}
<syntaxhighlight lang="wren">import "./iterate" for Stepped
import "./dynamic" for Enum
import "./fmt" for Fmt
 
/* external results */
var randrsl = List.filled(256, 0)
var randcnt = 0
 
/* internal state */
var mm = List.filled(256, 0)
var aa = 0
var bb = 0
var cc = 0
 
var GOLDEN_RATIO = 0x9e3779b9
 
var isaac = Fn.new {
cc = cc + 1 // cc just gets incremented once per 256 results
bb = bb + cc // then combined with bb
for (i in 0..255) {
var x = mm[i]
var j = i % 4
aa = (j == 0) ? aa ^ (aa << 13) :
(j == 1) ? aa ^ (aa >> 6) :
(j == 2) ? aa ^ (aa << 2) :
(j == 3) ? aa ^ (aa >> 16) : aa
aa = aa + mm[(i + 128) % 256]
var y = mm[(x >> 2) % 256] + aa + bb
mm[i] = y
bb = mm[(y >> 10) % 256] + x
randrsl[i] = bb
}
randcnt = 0
}
 
/* if (flag == true), then use the contents of randrsl to initialize mm. */
var mix = Fn.new { |n|
n[0] = n[0] ^ (n[1] << 11)
n[3] = n[3] + n[0]
n[1] = n[1] + n[2]
n[1] = n[1] ^ (n[2] >> 2)
n[4] = n[4] + n[1]
n[2] = n[2] + n[3]
n[2] = n[2] ^ (n[3] << 8)
n[5] = n[5] + n[2]
n[3] = n[3] + n[4]
n[3] = n[3] ^ (n[4] >> 16)
n[6] = n[6] + n[3]
n[4] = n[4] + n[5]
n[4] = n[4] ^ (n[5] << 10)
n[7] = n[7] + n[4]
n[5] = n[5] + n[6]
n[5] = n[5] ^ (n[6] >> 4)
n[0] = n[0] + n[5]
n[6] = n[6] + n[7]
n[6] = n[6] ^ (n[7] << 8)
n[1] = n[1] + n[6]
n[7] = n[7] + n[0]
n[7] = n[7] ^ (n[0] >> 9)
n[2] = n[2] + n[7]
n[0] = n[0] + n[1]
}
 
var randinit = Fn.new { |flag|
aa = 0
bb = 0
cc = 0
var n = List.filled(8, GOLDEN_RATIO)
for (i in 0..3) mix.call(n) // scramble the array
 
for (i in Stepped.new(0..255, 8)) { // fill in mm with messy stuff
if (flag) { // use all the information in the seed
for (j in 0..7) {
n[j] = n[j] + randrsl[i + j]
}
}
mix.call(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 Stepped.new(0..255, 8)) {
for (j in 0..7) n[j] = n[j] + mm[i + j]
mix.call(n)
for (j in 0..7) mm[i + j] = n[j]
}
}
 
isaac.call() // fill in the first set of results
randcnt = 0 // prepare to use the first set of results
}
 
var iRandom = Fn.new {
var r = randrsl[randcnt]
randcnt = randcnt + 1
if (randcnt > 255) {
isaac.call()
randcnt = 0
}
return r & 0xffffffff
}
 
/* Get a random character (as Num) in printable ASCII range */
var iRandA = Fn.new { (iRandom.call() % 95 + 32) }
 
/* Seed ISAAC with a string */
var iSeed = Fn.new { |seed, flag|
for (i in 0..255) mm[i] = 0
var m = seed.count
for (i in 0..255) {
/* in case seed has less than 256 elements */
randrsl[i] = (i >= m) ? 0 : seed[i].bytes[0]
}
/* initialize ISAAC with seed */
randinit.call(flag)
}
 
/* XOR cipher on random stream. Output: ASCII string */
var vernam = Fn.new { |msg|
var len = msg.count
var v = List.filled(len, 0)
var i = 0
for (b in msg.bytes) {
v[i] = (iRandA.call() ^ b) & 0xff
i = i + 1
}
return v.map { |b| String.fromByte(b) }.join()
}
 
/* constants for Caesar */
var MOD = 95
var START = 32
/* cipher modes for Caesar */
var CipherMode = Enum.create("CipherMode", ["ENCIPHER", "DECIPHER", "NONE"])
 
/* Caesar-shift a printable character */
var caesar = Fn.new { |m, ch, shift, modulo, start|
var sh = (m == CipherMode.DECIPHER) ? -shift : shift
var n = (ch - start) + sh
n = n % modulo
if (n < 0) n = n + modulo
return String.fromByte(start + n)
}
 
/* Caesar-shift a string on a pseudo-random stream */
var caesarStr = Fn.new { |m, msg, modulo, start|
var sb = ""
/* Caesar-shift message */
for (b in msg.bytes) {
sb = sb + caesar.call(m, b, iRandA.call(), modulo, start)
}
return sb
}
 
var toHexByteString = Fn.new { |s|
return s.bytes.map { |b| Fmt.swrite("$02X", b) }.join()
}
 
var msg = "a Top Secret secret"
var key = "this is my secret key"
 
// Vernam & Caesar ciphertext
iSeed.call(key, true)
var vctx = vernam.call(msg)
var cctx = caesarStr.call(CipherMode.ENCIPHER, msg, MOD, START)
 
// Vernam & Caesar plaintext
iSeed.call(key, true)
var vptx = vernam.call(vctx)
var cptx = caesarStr.call(CipherMode.DECIPHER, cctx, MOD, START)
 
// Program output
System.print("Message : %(msg)")
System.print("Key : %(key)")
System.print("XOR : %(toHexByteString.call(vctx))")
System.print("XOR dcr : %(vptx)")
System.print("MOD : %(toHexByteString.call(cctx))")
System.print("MOD dcr : %(cptx)")</syntaxhighlight>
 
{{out}}
<pre>
Message : a Top Secret secret
Key : this is my secret key
XOR : 1C0636190B1260233B35125F1E1D0E2F4C5422
XOR dcr : a Top Secret secret
MOD : 734270227D36772A783B4F2A5F206266236978
MOD dcr : a Top Secret secret
</pre>
9,476

edits