source: branches/eraser6/DefaultPlugins/ISAAC.cs @ 217

Revision 217, 1.7 KB checked in by lowjoel, 6 years ago (diff)

Optimized copy algorithm.

Line 
1using System;
2using System.Collections.Generic;
3using System.Text;
4
5using Eraser.Manager;
6
7namespace Eraser.DefaultPlugins
8{
9    /// <summary>
10    /// ISAAC CSPRNG.
11    /// </summary>
12    public class ISAAC : PRNG
13    {
14        public override string Name
15        {
16            get { return "ISAAC CSPRNG"; }
17        }
18
19        public override Guid GUID
20        {
21            get { return new Guid("{CB7DE02E-8067-4270-B115-70AB49F23BB7}"); }
22        }
23
24        public unsafe override void NextBytes(byte[] buffer)
25        {
26            lock (isaac)
27            {
28                for (int bytesGenerated = 0;
29                    bytesGenerated < buffer.Length * sizeof(byte);
30                    bytesGenerated += Rand.ISAAC.SIZE * sizeof(int))
31                {
32                    //Generate 256 ints.
33                    if (isaac.count == 0)
34                        isaac.Isaac();
35
36                    //Copy the data.
37                    fixed (int* src = isaac.rsl)
38                    fixed (byte* dest = &buffer[bytesGenerated])
39                    {
40                        //Advance to the end of the array of unused randomness.
41                        //byte* bSrc = (byte*)src;
42                        byte* pSrc = (byte*)(src + isaac.count);
43                        byte* pDest = dest;
44
45                        //Copy four bytes at a time, moving the source pointer backwards,
46                        //and the destination pointer forwards.
47                        int bytesToCopy = Math.Min(isaac.count * sizeof(int),
48                            buffer.Length - bytesGenerated);
49                        while (bytesToCopy >= 4)
50                        {
51                            pSrc -= sizeof(int);
52                            *(int*)pDest = *(int*)pSrc;
53                            pDest += sizeof(int);
54
55                            bytesToCopy -= sizeof(int);
56                            --isaac.count;
57                        }
58
59                        //Copy the remaining bytes over.
60                        if (bytesToCopy != 0)
61                        {
62                            while (bytesToCopy-- != 0)
63                                *pDest++ = *pSrc--;
64                            --isaac.count;
65                        }
66                    }
67                }
68            }
69        }
70
71        private Rand.ISAAC isaac = new Rand.ISAAC();
72    }
73}
Note: See TracBrowser for help on using the repository browser.