some updates
[iv.d.git] / arc4simple.d
blob1e1d0c2e523e4e0b0328e8e29e0014359288090f
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, version 3 of the License ONLY.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 module iv.arc4simple /*is aliced*/;
18 import iv.alice;
21 // ///////////////////////////////////////////////////////////////////////// //
22 struct ARC4Codec {
23 ubyte[256] m; // permutation table
24 ubyte x, y; // permutation indicies
26 nothrow @trusted @nogc:
27 this (const(void)[] key, usize skipBytes=4096) { reinit(key, skipBytes); }
29 void reinit (const(void)[] key, usize skipBytes=4096) {
30 assert(key.length > 0);
31 auto keybytes = cast(const ubyte*)key.ptr;
32 x = y = 0;
33 foreach (immutable f; 0..256) m[f] = cast(ubyte)f;
34 // create permutation table
35 usize kidx = 0;
36 ubyte c = 0;
37 foreach (immutable f; 0..256) {
38 auto kc = keybytes[kidx];
39 auto a = m[f];
40 c = (c+a+kc)&0xff;
41 m[f] = m[c];
42 m[c] = a;
43 if (++kidx == key.length) kidx = 0;
45 // discard first bytes
46 while (skipBytes--) {
47 x = (x+1)&0xff;
48 auto a = m[x];
49 y = (y+a)&0xff;
50 m[x] = m[y];
51 m[y] = a;
55 void processBuffer(T) (T[] buf) {
56 usize len = T.sizeof*buf.length;
57 auto data = cast(ubyte*)buf.ptr;
58 foreach (immutable _; 0..len) {
59 x = (x+1)&0xff;
60 auto a = m[x];
61 y = (y+a)&0xff;
62 auto bt = (m[x] = m[y]);
63 m[y] = a;
64 *data++ ^= m[(a+bt)&0xff];
70 // ///////////////////////////////////////////////////////////////////////// //
71 version(arc4_tests) unittest {
72 import std.algorithm;
73 import std.stdio;
74 writeln("unittest: arc4");
75 enum ubyte[] sourceData = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
76 enum ubyte[] encodedData = [51,27,44,79,153,231,133,220,143,156,178,63,31,238,28,138];
77 auto data = sourceData.dup;
79 auto a4 = ARC4Codec("asspole");
80 a4.processBuffer(data);
81 assert(equal(encodedData, data));
84 auto a4 = ARC4Codec("asspole");
85 a4.processBuffer(data);
86 assert(equal(sourceData, data));