cosmetix
[iv.d.git] / arc4simple.d
blobc6bc127fd16c91b5c350ddd584cc722bfbf88e05
1 /* Invisible Vector Library
2 * coded by Ketmar // Invisible Vector <ketmar@ketmar.no-ip.org>
3 * Understanding is not required. Only obedience.
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 module iv.arc4simple /*is aliced*/;
19 import iv.alice;
22 // ///////////////////////////////////////////////////////////////////////// //
23 struct ARC4Codec {
24 ubyte[256] m; // permutation table
25 ubyte x, y; // permutation indicies
27 nothrow @trusted @nogc:
28 this (const(void)[] key, usize skipBytes=4096) { reinit(key, skipBytes); }
30 void reinit (const(void)[] key, usize skipBytes=4096) {
31 assert(key.length > 0);
32 auto keybytes = cast(const ubyte*)key.ptr;
33 x = y = 0;
34 foreach (immutable f; 0..256) m[f] = cast(ubyte)f;
35 // create permutation table
36 usize kidx = 0;
37 ubyte c = 0;
38 foreach (immutable f; 0..256) {
39 auto kc = keybytes[kidx];
40 auto a = m[f];
41 c = (c+a+kc)&0xff;
42 m[f] = m[c];
43 m[c] = a;
44 if (++kidx == key.length) kidx = 0;
46 // discard first bytes
47 while (skipBytes--) {
48 x = (x+1)&0xff;
49 auto a = m[x];
50 y = (y+a)&0xff;
51 m[x] = m[y];
52 m[y] = a;
56 void processBuffer(T) (T[] buf) {
57 usize len = T.sizeof*buf.length;
58 auto data = cast(ubyte*)buf.ptr;
59 foreach (immutable _; 0..len) {
60 x = (x+1)&0xff;
61 auto a = m[x];
62 y = (y+a)&0xff;
63 auto bt = (m[x] = m[y]);
64 m[y] = a;
65 *data++ ^= m[(a+bt)&0xff];
71 // ///////////////////////////////////////////////////////////////////////// //
72 version(arc4_tests) unittest {
73 import std.algorithm;
74 import std.stdio;
75 writeln("unittest: arc4");
76 enum ubyte[] sourceData = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
77 enum ubyte[] encodedData = [51,27,44,79,153,231,133,220,143,156,178,63,31,238,28,138];
78 auto data = sourceData.dup;
80 auto a4 = ARC4Codec("asspole");
81 a4.processBuffer(data);
82 assert(equal(encodedData, data));
85 auto a4 = ARC4Codec("asspole");
86 a4.processBuffer(data);
87 assert(equal(sourceData, data));