Three Dimensional Encryption | |
New visualization methodBit Level PrecisionBy Anthony Matarazzo |
|
Encrypt means to put (computer data) into a coded form. In the past, many different types of algorithms were used to code data. Most times, serious encryption algorithms, are used and are of interest by government bodies. This is because electronic communication is very fluid and tracing information id tedious for these parties.
In the past, the most widely known encryption success was Enigma. The Enigma machine is a German electro-mechanical rotor machine that changes character set upon each key press. In 1932, the Polish Cipher Bureau first broke the code. During World War II, many communications were successfully interpreted that aided in winning complex war battles. The machine had accessories developed that would print.
The three dimensional encryption algorithm uses data structures to represent bit information within the byte using coordinates within space. The space is defined to be a cube. The dimensions of the object, can also be exchanged or re-dimensioned to have a different length, width, and height. Each of the functions defined within this algorithm use these measurements to apply bounds upon the loop iterations. Operations are performed based upon a password or random private key. This key is needed to decode the information.
See Also
Importing the data into a logical data structure is accomplished using bit wise and. The powers of two, 1, 2, 4, 8, 16, 32, 64, 128 are position according to a bit location within a byte. Represented traditionally with the right most digit being the start - 1. Then moving left to 2^1=2, 2^2=4, etc. By calculating the total number of bytes in the package, 8*length produces the bit length of the package. Using a rounded up cube root of this product will give an approximation to the necessary bounds needed to host the data. Implementing standard loop counters for x,y and Z incrementing at each insertion will enable calculation of the bit location. There will usually be a segment upon the end that will need to be filled in because of the data not being a perfect cube in size. The extra data will need to be maintained even if the cube grows because all operations will depend on data passing through this location.
NOTE: This code is not complete yet. Updates will arrive as the book is developed further. You are invited to review.
The code below is a C example of the Cube Encryption Algorithm.
C
/************************************************************** Author: Anthony Matarazzo www.AlienTimes.com Description: A bit level encryption algorithm designed for financial processing upon the Internet. The program uses private keys and can select several portions from a larger key. The program divides a string of data into three dimensional structures that represent the information using binary within a three dimensional space. The information is stored inside a cube shape conceptually. Positions of the bits are changed based upon the data of the password. The password is the most important feature, operating as an instruction. The details of the password bytes must be known to decrypt. Since the algorithm operatins as a chain, cube, next frames rely more upon the previous operation. One operation incorrect and the hacker is deprived. Random data as a pure source is easier to generate in an analog universe. ***************************************************************/ /* Additional research options - - placing false information into the cube and then rolling changes to a specific point in time will add complexity to decryption. Time - Specifying character set, 5-bit all caps - 8 bit ASCII - Unicode exceptions - large file handling - package format for multiple files - compression without signature - visualization of the data - 3d cube rotation of bits during operation - testing and results section - server - client handshake - lib implementation - C++ core implementation - COM implementation - Java Implementation - library for opening an encrypted channel using this method - winsock - */ #include <cstdlib> #include <iostream> #include <bitset> #include <vector> #include <stdio.h> #include <math.h> using namespace std; #include "RandomNumber.h" #include "BitEncryption.h" BitEncryption::BitEncryption() { msData=0x00; mlDataSize=0; msOutput=0x00; mlOutputSize=0; msKey=0x00; mlKeySize=0; mlCubeSize=0; mlWidth=0; mlHeight=0; mRandomNumber=0x00; } BitEncryption::‾BitEncryption() { if(msData) delete []msData; if(msOutput) delete []msOutput; if(msKey) delete []msKey; if(mRandomNumber) delete mRandomNumber; } /********************************************************** float CubeRoot(float x) The function returns the cube root of the passed parameter - The value to calculate the cube root of - the data * The program uses the Interate portion which is less precise. The extra information is not needed. Where the function is used, the value is rounded. =================================================================== Function Source: http://people.freebsd.org/‾lstewart/references/apple_tr_kt32_cuberoot.pdf By Ken Turkowski, turk@apple.com **********************************************************/ float BitEncryption::CubeRoot(float x) { float fr, r; int ex, shx; /* Argument reduction */ fr = frexp(x, &ex); /* separate into mantissa and exponent */ shx = ex % 3; if (shx > 0) shx -= 3; /* compute shx such that (ex - shx) is divisible by 3 */ ex = (ex - shx) / 3; /* exponent of cube root */ fr = ldexp(fr, shx); /* Compute seed with a quadratic approximation */ fr = (-0.46946116F * fr + 1.072302F) * fr + 0.3812513F;/* 0.5<=fr<1 */ r = ldexp(fr, ex); /* 6 bits of precision */ /* Newton-Raphson iterations */ r = (float)(2.0/3.0) * r + (float)(1.0/3.0) * x / (r * r); /* 12 bits */ r = (float)(2.0/3.0) * r + (float)(1.0/3.0) * x / (r * r); /* 24 bits */ #if 0 /* Use quartic rational polynomial with error < 2^(-24) */ fr = ((((45.2548339756803022511987494 * fr + 192.2798368355061050458134625) * fr + 119.1654824285581628956914143) * fr + 13.43250139086239872172837314) * fr + 0.1636161226585754240958355063) / ((((14.80884093219134573786480845 * fr + 151.9714051044435648658557668) * fr + 168.5254414101568283957668343) * fr + 33.9905941350215598754191872) * fr + 1.0); r = ldexp(fr, ex); /* 24 bits of precision */ #endif return(r); } /***************************************************** The routine tests if a bit is on within the x, y, z state within the unsigned char stream *****************************************************/ void inline BitEncryption::SetBit(long x,long y, long z, bool rbBit) { long lByteIndex; int iShiftLeft; long lBitIndex; float fTmp; // calculate the size of the cube. // other choice is to change the cube to rectangle fTmp=CubeRoot(mlDataSize*8); fTmp+=.9; mlCubeSize=(long) fTmp; mlCubeSize=(long) fTmp; lBitIndex=(x+ (y*mlCubeSize) + (mlCubeSize*mlCubeSize*z)); lByteIndex=lBitIndex / 8; iShiftLeft=lBitIndex % 8; unsigned char cTmp; if(rbBit){ cTmp=1<<iShiftLeft; msData[lByteIndex]|=cTmp; } else { msData[lByteIndex]^=‾cTmp; } } bool inline BitEncryption::GetBit(long x,long y, long z) { long lByteIndex; int iShiftLeft; long lBitIndex; bool bRet; float fTmp; // calculate the size of the cube. // other choice is to change the cube to rectangle fTmp=CubeRoot(mlDataSize*8); fTmp+=.9; mlCubeSize=(long) fTmp; mlCubeSize=(long) fTmp; lBitIndex=(x+ (y*mlCubeSize) + (mlCubeSize*mlCubeSize*z)); lByteIndex=lBitIndex / 8; iShiftLeft=lBitIndex % 8; if(msData[lByteIndex]&(1<<iShiftLeft) == 1) { bRet=true; } else { bRet=false; } return(bRet); } /********************************************************** **********************************************************/ void inline BitEncryption::SwapBits(long lX1, long lY1, long lZ1, long lX2, long lY2, long lZ2) { bool bBitTmp1; bool bBitTmp2; bBitTmp1=GetBit(lX1,lY1,lZ1); bBitTmp2=GetBit(lX2,lY2,lZ2); SetBit(lX1,lY1,lZ1, bBitTmp2); SetBit(lX2,lY2,lZ2, bBitTmp1); } /********************************************************** **********************************************************/ long BitEncryption::SwapPlanes(int iDir, long lPosition, long lSeed, long lAmt) { long lRet=0; long lHash; long lp1; long lp2; long lLoop; long lLoop1; long lLoop2; long lPlane1; long lPlane2; /* create a snapshot of the point in time of the algorithm and compress the information using the hash function. */ // dHash=HashSWA(lPosition,lSeed,msKey+lPosition,RandomLong((long) *(msKey+lPosition), lSeed*lPosition*lAmt); if(lPosition> mlKeySize-4) { lHash=(long) *(msKey+(lPosition-4)); } else { lHash=(long) *(msKey+lPosition); } /* first parameter according to algorithm has to be between second parameter according to algorithm has to be between */ lp1=lHash%31328; lp2=lSeed%30081; /* set the uniform random number generator */ mRandomNumber->RandomInitialise(lp1,lp2); for(lLoop=0;lLoop<lAmt;lLoop++) { lPlane1=mRandomNumber->RandomLong(0, mlCubeSize); lPlane2=lPlane1; // make sure two unique planes are selected within the cube while(lPlane1==lPlane2) { lPlane2=mRandomNumber->RandomLong(0, mlCubeSize); } for(lLoop1=0;lLoop1<mlCubeSize;lLoop1++) { for(lLoop2=0;lLoop2<mlCubeSize;lLoop2++) { iDir=iDir%3; switch(iDir) { case 0: SwapBits(lPlane1,lLoop1,lLoop2, lPlane2,lLoop1,lLoop2); break; case 1: SwapBits(lLoop1,lPlane1,lLoop2, lLoop1,lPlane2,lLoop2); break; case 2: SwapBits(lLoop1,lLoop2,lPlane1, lLoop1,lLoop2,lPlane2); break; } } } } return lRet; } /********************************************************** **********************************************************/ long BitEncryption::SwapRays(long lPosition, long lSeed, long lAmt) { long lRet=0; return lRet; } /********************************************************** **********************************************************/ unsigned char *BitEncryption::GenerateBitmap(long lKeyPosition, long lSeed, long lAmt) { unsigned char *lpRet=0x00; long lLoop; lpRet=new unsigned char[lAmt]; for(lLoop=0;lLoop<lAmt;lLoop++) { lpRet[lLoop]=(unsigned char)mRandomNumber->RandomInt(0,255); } return lpRet; } /********************************************************** **********************************************************/ long BitEncryption::ApplyBitmap(int iFace, unsigned char *rsBitmap, long lSize) { long lRet=0; long lX1; long lY1; long lZ1; long lLoop2; long lTmp; long lPos=0; for(lX1=0;lX1<mlCubeSize;lX1++) { for(lY1=0;lY1<mlCubeSize;lY1++) { for(lZ1=0;lZ1<mlCubeSize;lZ1++) { switch(iFace) { case 0: // z face lTmp=lZ1+rsBitmap[lPos]; if(lTmp>mlCubeSize) lTmp=(lLoop2+rsBitmap[lPos]) % mlCubeSize; SwapBits(lX1,lY1,lZ1, lX1,lY1,lTmp); break; case 1: lTmp=lY1+rsBitmap[lPos]; if(lTmp>mlCubeSize) lTmp=(lY1+rsBitmap[lPos]) % mlCubeSize; SwapBits(lX1,lY1,lZ1, lX1,lTmp,lZ1); break; case 2: lTmp=lX1+rsBitmap[lPos]; if(lTmp>mlCubeSize) lTmp=(lX1+rsBitmap[lPos]) % mlCubeSize; SwapBits(lX1,lY1,lZ1, lTmp,lY1,lZ1); break; } lPos++; if(lPos>lSize) { lPos=0; } } } } return lRet; } /********************************************************** **********************************************************/ long BitEncryption::RotateXPlane(long lPosition, long lSeed, long lAmt) { long lRet=0; return lRet; } /********************************************************** **********************************************************/ long BitEncryption::RotateYPlane(long lPosition, long lSeed, long lAmt) { long lRet=0; return lRet; } /********************************************************** **********************************************************/ long BitEncryption::RotateZPlane(long lPosition, long lSeed, long lAmt) { long lRet=0; return lRet; } /********************************************************** **********************************************************/ long BitEncryption::GenerateNonlinearPath(vector<cBitPoint>& rvPath, long lKeyPosition, long lSeed) { long lRet=0; return lRet; } /********************************************************** **********************************************************/ long BitEncryption::GenerateSpiralPath(vector<cBitPoint>& rvPath, long lKeyPosition, long lSeed) { long lRet=0; return lRet; } /********************************************************** **********************************************************/ long BitEncryption::GenerateCurve(vector<cBitPoint>& rvPath, long lKeyPosition, long lSeed) { long lRet=0; return lRet; } /********************************************************** **********************************************************/ long BitEncryption::SwapPaths(vector<cBitPoint>& PathA, vector<cBitPoint>& PathB) { long lRet=0; return lRet; } /********************************************************** **********************************************************/ long BitEncryption::PushRay(long lPosition, long lSeed, long lAmt) { long lRet=0; return lRet; } /********************************************************** **********************************************************/ long BitEncryption::PushPath(vector<cBitPoint>& PathA, long lKeyPosition, long lSeed ) { long lRet=0; // vector<cBitPoint>::iterator p2; for (vector<cBitPoint>::iterator p=PathA.begin(); p!=PathA.end(); ++p) { if(p==PathA.begin()) { // p2=PathA.end(); // SwapBits(p.x, p.y, p.z, p2.x, p2.y, p2.z); } else { // p2=p+1; // SwapBits(p.x, p.y, p.z, p2.x, p2.y, p2.z); } } return lRet; } /********************************************************** **********************************************************/ long BitEncryption::SwapSubCubes(long lPosition, long lSeed, long lAmt) { long lRet=0; long lX; long lY; long lZ; long lPointAX; long lPointAY; long lPointAZ; long lPointBX; long lPointBY; long lPointBZ; long lLoop; long lSubCube; for(lLoop=0;lLoop<lAmt;lLoop++) { lSubCube=mlCubeSize / mRandomNumber->RandomInt(0,mlCubeSize/2); lPointAX=mRandomNumber->RandomInt(0,mlCubeSize); lPointAY=mRandomNumber->RandomInt(0,mlCubeSize); lPointAZ=mRandomNumber->RandomInt(0,mlCubeSize); lPointBX=mRandomNumber->RandomInt(0,mlCubeSize); lPointBY=mRandomNumber->RandomInt(0,mlCubeSize); lPointBZ=mRandomNumber->RandomInt(0,mlCubeSize); for(lX=0;lX<lSubCube;lX++) for(lY=0;lY<lSubCube;lY++) for(lZ=0;lZ<lSubCube;lZ++) SwapBits(lX+lPointAX, lY+lPointAY, lZ+lPointAZ, lX+lPointBX, lY+lPointBY, lZ+lPointBZ); } return lRet; } /********************************************************** **********************************************************/ long BitEncryption::RotateSubCube(long lPosition, long lSeed, long lAmt) { long lRet=0; return lRet; } /********************************************************** **********************************************************/ long BitEncryption::RandomizeCharacterSet(long lKeyPosition, long lSeed) { long lRet=0; return lRet; } /********************************************************** long InverseBits(lPosition, lSeed, lAmt) The function selects a given number of points within the cube and inverses the data; **********************************************************/ long BitEncryption::InverseBits(long lPosition, long lSeed, long lAmt) { long lRet=0; long lHash; long lp1; long lp2; long lLoop; long lX1; long lY1; long lZ1; bool bBit; /* create a snapshot of the point in time of the algorithm and compress the information using the hash function. */ // dHash=HashSWA(lPosition,lSeed,msKey+lPosition,RandomLong((long) *(msKey+lPosition), lSeed*lPosition*lAmt); if(lPosition> mlKeySize-4) { lHash=(long) *(msKey+(lPosition-4)); } else { lHash=(long) *(msKey+lPosition); } /* first parameter according to algorithm has to be between second parameter according to algorithm has to be between */ lp1=lHash%31328; lp2=lSeed%30081; /* set the uniform random number generator */ mRandomNumber->RandomInitialise(lp1,lp2); for(lLoop=0;lLoop<lAmt;lLoop++) { lX1=mRandomNumber->RandomLong(0, mlCubeSize); lY1=mRandomNumber->RandomLong(0, mlCubeSize); lZ1=mRandomNumber->RandomLong(0, mlCubeSize); bBit=GetBit(lX1,lY1,lZ1); if(bBit) SetBit(lX1,lY1,lZ1,false); else SetBit(lX1,lY1,lZ1,true); } return lRet; } /********************************************************** **********************************************************/ long BitEncryption::VariableMatrixGroupOddEvenSwap(long lPosition, long lSeed, long lAmt) { long lRet=0; return lRet; } /********************************************************** **********************************************************/ long BitEncryption::NoiseExpansion(long lPosition, long lSeed, long lAmt) { long lRet=0; return lRet; } /********************************************************** int Encrypt(char *szPassword, char *szData, char *szOutput) The main function to invoke. - the password - the data - place for the output **********************************************************/ #define MAX_OPERATIONS 21 long BitEncryption::Encrypt(unsigned char *sInput, long lInputSize, unsigned char *szKey, long lKeySize, unsigned char **szOutput) { long lOperation=0; long lPosition=0; unsigned char *pBitmap; cBitPoint lP1; cBitPoint lP2; unsigned char *lpchKey; long lSeed=0; long lAmt=0; long lDir=0; vector<cBitPoint> lPath1; vector<cBitPoint> lPath2; RandomNumber *pLocalRandomAmt; mRandomNumber=new RandomNumber(); pLocalRandomAmt=new RandomNumber(mRandomNumber->RandomInt(0,30000),mRandomNumber->RandomInt(0,30000)); /* A Usual set for the encryption algorithm should be measured to be a certain size. This will give a rating to the cipher strength that is proportional to the size. */ mlDataSize=lInputSize; msData=new unsigned char[mlDataSize]; memcpy(msData,sInput,lInputSize); mlOutputSize=mlDataSize; // calculate the size of the cube float fTmp=CubeRoot(mlDataSize*8); fTmp+=.9; mlCubeSize=(long) fTmp; mlKeySize=lKeySize; msKey=new unsigned char[mlKeySize]; memcpy(msKey,szKey, mlKeySize); lpchKey=szKey; lPosition=0; while(lPosition<lKeySize) { unsigned char cTmp=(unsigned char)(*lpchKey); int iTmp=cTmp / MAX_OPERATIONS; int iTmp2=cTmp - (iTmp*MAX_OPERATIONS); lOperation=iTmp2; if(lOperation==0) lOperation=1; lAmt=pLocalRandomAmt->RandomInt(0,10); lSeed=pLocalRandomAmt->RandomInt(0,32000); /* perform operations based upon the password */ switch(lOperation) { /* swap lAmt planes of a given face. */ case 1: SwapPlanes(0, lPosition, lSeed, lAmt); break; case 2: SwapPlanes(1, lPosition, lSeed, lAmt); break; case 3: SwapPlanes(2, lPosition, lSeed, lAmt); break; /* swap two rays of data upon a given face. That is the bits that follow the selected point upon the face are swap with the other. Since the face may be different for one ray and the other, The data bits within path are recorded and then the information is swapped. */ case 4: SwapRays(lPosition, lSeed, lAmt); break; /* A cube has six sides. Given a face, a point is selected within the face. This information is pushed through and the ray data rolled back into the other side of the cube. A direction is established with an amount to roll. The direction is shown by the sign of the amount - which is a logical face. */ case 5: PushRay(lPosition, lSeed, lAmt); break; /* apply a one dimension bitmap impression to a face */ case 8: pBitmap=0x00; pBitmap=GenerateBitmap(lPosition, lSeed, lAmt); ApplyBitmap(0, pBitmap, lAmt); delete []pBitmap; break; case 9: pBitmap=0x00; pBitmap=GenerateBitmap(lPosition, lSeed, lAmt); ApplyBitmap(1, pBitmap, lAmt); delete []pBitmap; break; case 10: pBitmap=0x00; pBitmap=GenerateBitmap(lPosition, lSeed, lAmt); ApplyBitmap(2, pBitmap, lAmt); delete []pBitmap; break; /* rotate a plane within the cube */ case 11: RotateXPlane(lPosition, lSeed, lAmt); break; case 12: RotateYPlane(lPosition, lSeed, lAmt); break; case 13: RotateZPlane(lPosition, lSeed, lAmt); break; /* Generate two nonlinear paths from one face to the otherside then swap the two. WHen the paths are not of equal size, information resdue is still maintained. - within the cube a path is generated that is shaped like a tree branch. the information along the path is extracted. A second path is generated that contains the same amount of information. This information is extracted. The two information branches are swapped along the two paths. */ case 14: // generates numbers for the path lPath1.clear(); lPath2.clear(); GenerateNonlinearPath(lPath1, lPosition, lSeed); GenerateNonlinearPath(lPath2, lPosition, lSeed); SwapPaths(lPath1, lPath2); lPath1.clear(); lPath2.clear(); break; /* generate a random order for the character set. */ case 15: RandomizeCharacterSet(lPosition, lSeed); break; case 16: GenerateSpiralPath(lPath1, lPosition, lSeed); GenerateSpiralPath(lPath2, lPosition, lSeed); SwapPaths(lPath1, lPath2); break; /* swap two sub cubes within the larger cube */ case 17: SwapSubCubes(lPosition, lSeed, lAmt); break; /* rotate a sube cube within the larget cube */ case 18: RotateSubCube(lPosition, lSeed, lAmt); break; case 19: /* representing each cube position (part) as being a distinct segment, the segment length derived using a uniform random, enables a relationship to exist with other portions of the cube. The ability to tie this relationship to visually disjointed portions of the space will amplify complexity of the decryption. This ties relationships using proportional distances to the face. Changing faces using a uniform random number seeded by the password position enables decryption using the key.*/ VariableMatrixGroupOddEvenSwap(lPosition, lSeed, lAmt); break; case 20: /* the algorithm will expand the cube with a small amount of data. One pass will not double the suze of the cube. The amount of data added, the data and the position of the data are based upon the random uniform seeded by location. It is expected that multiple passes through this routine is accomplished using the hidden instruction key. */ NoiseExpansion(lPosition, lSeed, lAmt); break; case 21: /* This routine uses a curved line segment with one bend. The height of the form will be determined by its position within space. The bend will occur at a uniform position and effect directly the height. Once a curve shape is calculated, this information is used within the three planes, x,y,z. A rotation of information along this curve occurs between the two planes. So for example x=z y=x See: B騷ier curve http://en.wikipedia.org/wiki/B%C3%A9zier_curve */ lPath1.clear(); lPath2.clear(); GenerateCurve(lPath1, lPosition, lSeed); GenerateCurve(lPath2, lPosition, lSeed); SwapPaths(lPath1, lPath2); break; case 22: /* this option will erase data or reverse the bit status upon a select group of pixels. Using the UNARY operation, 1=0 and 0=1, the operation can be undone. A good transform for basic data, the selection of x,y,z coordinates is particular. */ InverseBits(lPosition, lSeed, lAmt); break; default: break; } lpchKey++; lPosition++; } delete pLocalRandomAmt; pLocalRandomAmt=0x00; delete mRandomNumber; mRandomNumber=0x00; *szOutput= new unsigned char[mlOutputSize+1]; memset(*szOutput,0x00,mlOutputSize+1); memcpy(*szOutput, msData,mlOutputSize); return(mlOutputSize); } /********************************************************** int main(int argc, char **argv) The main function - called at start. - the number of parameters - the parameters **********************************************************/ long BitEncryption::Decrypt(unsigned char *sInput, long lInputSize, unsigned char *szKey, long lKeySize, unsigned char **szOutput) { long lRet=0; return(lRet); } /********************************************************** int main(int argc, char **argv) The main function - called at start. - the number of parameters - the parameters **********************************************************/ int main(int argc, char **argv) { int n; BitEncryption *cBits = new BitEncryption(); unsigned char *szPassword=new unsigned char[255]; unsigned char *szData=new unsigned char[255]; unsigned char *szOut=0x00; long lOutputSize; /* if (argc < 2) { printf("usage: encrypt n¥n" "password.txt data.txt output.txt [-encrypt -decrypt]¥n"); return 1; }*/ memset(szPassword,255,0x00); memset(szData,255,0x00); strcpy((char *)szPassword,"THEPASSWORD"); strcpy((char *)szData,"ABCDEFHIJKLMNOPQRSTUVWXYZ"); printf("password = %s¥n data = %s¥n", szPassword, szData); lOutputSize=cBits->Encrypt(szData, strlen((char *)szData), szPassword, strlen((char *)szPassword), &szOut); printf("data = %s¥n", szOut); delete []szData; delete []szPassword; delete []szOut; system("PAUSE"); return EXIT_SUCCESS; }
C
#include <vector> class cBitPoint { public: int x; int y; int z; cBitPoint() {}; ~cBitPoint() {}; }; bool operator==(const cBitPoint& a, const cBitPoint& b) { return a.x == b.x && a.y == b.y && a.z == b.z; } bool operator!=(const cBitPoint& a, const cBitPoint& b) { return !(a.x == b.x && a.y == b.y && a.z == b.z); } /******************************* The Main Class *******************************/ class BitEncryption { public: BitEncryption(); ~BitEncryption(); long Encrypt(unsigned char *sInput, long lInputSize, unsigned char *szKey, long lKeySize, unsigned char **szOutput); long Decrypt(unsigned char *sInput, long lInputSize, unsigned char *szKey, long lKeySize, unsigned char **szOutput); private: float CubeRoot(float x); bool GetBit(long y, long y, long z); void SetBit(long x, long y, long z, bool rbVal); void SwapBits(long X1, long y1, long z1, long X2, long y2, long z2 ); // Operations long SwapPlanes(int iDir, long lPosition, long lSeed, long lAmt); long SwapRays(long lPosition, long lSeed, long lAmt); unsigned char *GenerateBitmap(long lKeyPosition, long lSeed, long lAmt); long ApplyBitmap(int iFace, unsigned char *rsBitmap, long lSize); long RotateXPlane(long lPosition, long lSeed, long lAmt); long RotateYPlane(long lPosition, long lSeed, long lAmt); long RotateZPlane(long lPosition, long lSeed, long lAmt); long GenerateNonlinearPath(vector<cBitPoint>& rPath, long lKeyPosition, long lSeed); long GenerateSpiralPath(vector<cBitPoint>& rPath, long lKeyPosition, long lSeed); long GenerateCurve(vector<cBitPoint>& rPath,long lKeyPosition, long lSeed); long SwapPaths(vector<cBitPoint>& PathA, vector<cBitPoint>& PathB); long PushPath(vector<cBitPoint>& PathA, long lKeyPosition, long lSeed ); long PushRay(long lPosition, long lSeed, long lAmt); long SwapSubCubes(long lPosition, long lSeed, long lAmt); long RotateSubCube(long lPosition, long lSeed, long lAmt); long RandomizeCharacterSet(long lKeyPosition, long lSeed); long InverseBits(long lPosition, long lSeed, long lAmt); long VariableMatrixGroupOddEvenSwap(long lPosition, long lSeed, long lAmt); long NoiseExpansion(long lPosition, long lSeed, long lAmt); // changing the byte base does have noticeable signatures. // and must be effectively synchronized to achieve hidden and // obscure results. long ChangeByteBase(long lKeyPosition, long lSeed); private: unsigned char *msData; long mlDataSize; unsigned char *msOutput; long mlOutputSize; unsigned char *msKey; long mlKeySize; long mlCubeSize; RandomNumber *mRandomNumber; long mlWidth; long mlHeight; };
C
#include "RandomNumber.h" #include <math.h> /* This Random Number Generator is based on the algorithm in a FORTRAN version published by George Marsaglia and Arif Zaman, Florida State University; ref.: see original comments below. At the fhw (Fachhochschule Wiesbaden, W.Germany), Dept. of Computer Science, we have written sources in further languages (C, Modula-2 Turbo-Pascal(3.0, 5.0), Basic and Ada) to get exactly the same test results compared with the original FORTRAN version. April 1989 Karl-L. Noell <NOELL@DWIFH1.BITNET> and Helmut Weber <WEBER@DWIFH1.BITNET> This random number generator originally appeared in "Toward a Universal Random Number Generator" by George Marsaglia and Arif Zaman. Florida State University Report: FSU-SCRI-87-50 (1987) It was later modified by F. James and published in "A Review of Pseudo- random Number Generators" THIS IS THE BEST KNOWN RANDOM NUMBER GENERATOR AVAILABLE. (However, a newly discovered technique can yield a period of 10^600. But that is still in the development stage.) It passes ALL of the tests for random number generators and has a period of 2^144, is completely portable (gives bit identical results on all machines with at least 24-bit mantissas in the floating point representation). The algorithm is a combination of a Fibonacci sequence (with lags of 97 and 33, and operation "subtraction plus one, modulo one") and an "arithmetic sequence" (using subtraction). Use IJ = 1802 & KL = 9373 to test the random number generator. The subroutine RANMAR should be used to generate 20000 random numbers. Then display the next six random numbers generated multiplied by 4096*4096 If the random number generator is working properly, the random numbers should be: 6533892.0 14220222.0 7275067.0 6172232.0 8354498.0 10633180.0 */ RandomNumber::RandomNumber() { test=FALSE; } RandomNumber::~RandomNumber() { } /* This is the initialization routine for the random number generator. NOTE: The seed variables can have values between: 0 <= IJ <= 31328 0 <= KL <= 30081 The random number sequences created by these two seeds are of sufficient length to complete an entire calculation with. For example, if sveral different groups are working on different parts of the same calculation, each group could be assigned its own IJ seed. This would leave each group with 30000 choices for the second seed. That is to say, this random number generator can create 900 million different subsequences -- with each subsequence having a length of approximately 10^30. */ void RandomNumber::RandomInitialise(int ij,int kl) { double s,t; int ii,i,j,k,l,jj,m; /* Handle the seed range errors First random number seed must be between 0 and 31328 Second seed must have a value between 0 and 30081 */ if (ij < 0 || ij > 31328 || kl < 0 || kl > 30081) { ij = 1802; kl = 9373; } i = (ij / 177) % 177 + 2; j = (ij % 177) + 2; k = (kl / 169) % 178 + 1; l = (kl % 169); for (ii=0; ii<97; ii++) { s = 0.0; t = 0.5; for (jj=0; jj<24; jj++) { m = (((i * j) % 179) * k) % 179; i = j; j = k; k = m; l = (53 * l + 1) % 169; if (((l * m % 64)) >= 32) s += t; t *= 0.5; } u[ii] = s; } c = 362436.0 / 16777216.0; cd = 7654321.0 / 16777216.0; cm = 16777213.0 / 16777216.0; i97 = 97; j97 = 33; test = TRUE; } /* This is the random number generator proposed by George Marsaglia in Florida State University Report: FSU-SCRI-87-50 */ double RandomNumber::RandomUniform(void) { double uni; /* Make sure the initialisation routine has been called */ if (!test) RandomInitialise(1802,9373); uni = u[i97-1] - u[j97-1]; if (uni <= 0.0) uni++; u[i97-1] = uni; i97--; if (i97 == 0) i97 = 97; j97--; if (j97 == 0) j97 = 97; c -= cd; if (c < 0.0) c += cm; uni -= c; if (uni < 0.0) uni++; return(uni); } /* ALGORITHM 712, COLLECTED ALGORITHMS FROM ACM. THIS WORK PUBLISHED IN TRANSACTIONS ON MATHEMATICAL SOFTWARE, VOL. 18, NO. 4, DECEMBER, 1992, PP. 434-435. The function returns a normally distributed pseudo-random number with a given mean and standard devaiation. Calls are made to a function subprogram which must return independent random numbers uniform in the interval (0,1). The algorithm uses the ratio of uniforms method of A.J. Kinderman and J.F. Monahan augmented with quadratic bounding curves. */ double RandomNumber::RandomGaussian(double mean,double stddev) { double q,u,v,x,y; /* Generate P = (u,v) uniform in rect. enclosing acceptance region Make sure that any random numbers <= 0 are rejected, since gaussian() requires uniforms > 0, but RandomUniform() delivers >= 0. */ do { u = RandomUniform(); v = RandomUniform(); if (u <= 0.0 || v <= 0.0) { u = 1.0; v = 1.0; } v = 1.7156 * (v - 0.5); /* Evaluate the quadratic form */ x = u - 0.449871; y = fabs(v) + 0.386595; q = x * x + y * (0.19600 * y - 0.25472 * x); /* Accept P if inside inner ellipse */ if (q < 0.27597) break; /* Reject P if outside outer ellipse, or outside acceptance region */ } while ((q > 0.27846) || (v * v > -4.0 * log(u) * u * u)); /* Return ratio of P's coordinates as the normal deviate */ return (mean + stddev * v / u); } /* Return random integer within a range, lower -> upper INCLUSIVE */ int RandomNumber::RandomInt(int lower,int upper) { return((int)(RandomUniform() * (upper - lower + 1)) + lower); } long RandomNumber::RandomLong(long lower,long upper) { return((long)(RandomUniform() * (upper - lower + 1)) + lower); } /* Return random float within a range, lower -> upper */ double RandomNumber::RandomDouble(double lower,double upper) { return((upper - lower) * RandomUniform() + lower); }
C
#define FALSE 0 #define TRUE 1 class RandomNumber { public: RandomNumber(); RandomNumber(int ij,int kl) {RandomInitialise(ij,kl);} ~RandomNumber(); void RandomInitialise(int ij,int kl); double RandomUniform(void); double RandomGaussian(double mean,double stddev); int RandomInt(int lower,int upper); long RandomLong(long lower,long upper); double RandomDouble(double lower,double upper); private: double u[97],c,cd,cm; int i97,j97; int test; };
Testing an algorithm of this nature can take form in many tasks. The primary tasks according to work is that the algorithm be a) precise b) robust and c) high performance. The implementation for this research project works first on precision. Precision includes many times of the algorithm running until completeness.