Code archives/Algorithms/LCG 32bits Cipher
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
A first simple cipher, based on 2 functions (lib), and a working GUI example (app). A little documentation in LCG 32bits_lib.bmx, more infos about LCG : https://en.wikipedia.org/wiki/Linear_congruential_generator LCG 32bits Cipher_app.bmx | |||||
' LCG 32bits Cipher_lib.bmx ' '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Linear Congruential Generator (LCG) Cipher/Decipher ' ' LCG is an algorithm to generate a sequence of pseudorandom numbers. Each number in ' the sequence is based on the previous one. For the first number, a seed is used. ' ' number = (seed * a + c) Mod m ' then seed = number ' etc... ' ' Different parameters affect the quality of the randomness : ' - a : multiplier ' - c : increment ' - m : modulo ' ' You can find more infos about LCG and proven parameters on wikipedia : ' (linear congruential generator) ' ' A cipher based on LCG is considered weak to frequency analysis because of the ' linearity wich permits to break m, a and c values with mathematics. However, it ' will be enough protection against a non initiated curious user, and combined with ' XOR it is suitable to protect non crucial files. Also, it's fast and light. ' ' Here, numbers are simply ciphered 4 bytes by 4 bytes (32 bits), using XOR and LCG. ' It could be extended to cipher 8 bytes by 8 bytes (64 bits), using Long, but one ' would break 64 bits as easily as 32 bits, if he knows what he is doing. ' ' Both functions work with banks, you can read a ciphered file with LoadBank(file$), ' call the decipher function and read the original file in the returned bank. You ' can write the original file back with SaveBank(decipherBank,file) if you want. ' ' The seed is like a secret key. It is the first number of the random sequence, so ' deciphering with a wrong key will mess up everything after. If you don't provide ' a key when ciphering (0), a random one is chosen and stored in the ciphered file. ' All you'll have to know to decipher are the parameters used to cipher. If you ' provide a key when ciphering, it won't be stored in the ciphered file so you'll ' have to remember and provide both key and parameters to decipher (stronger). ' ' Flanker, 2017 (this is my first try in ciphering, take it easy :) ' '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Function LCG32Cipher:TBank(dataIn:TBank,a:Int=16807,c:Int=2^31-1,m:Int=0,seed:Int=0) Local pollTimer:Int = MilliSecs() ' <<<<< Only used for the GUI example, remove if necessary Local dataHeader:Int Local dataOffset:Int Local dataSize:Int = BankSize(dataIn) Local dataOut:TBank = CreateBank(4 + dataSize) If dataSize Mod 4 > 0 ResizeBank(dataIn,dataSize + 4-(dataSize Mod 4)) ResizeBank(dataOut,BankSize(dataOut) + 4-(dataSize Mod 4)) EndIf PokeInt dataOut,dataOffset,dataSize dataOffset = dataOffset + 4 If seed = 0 seed = Rand(2^31-1) ResizeBank(dataOut,BankSize(dataOut)+4) PokeInt dataOut,dataOffset,seed dataOffset = dataOffset + 4 EndIf dataHeader = dataOffset While dataOffset-dataHeader < BankSize(dataIn) Local valueIn:Int = PeekInt(dataIn,dataOffset-dataHeader) Local valueOut:Int = valueIn~seed ' XOR PokeInt(dataOut,dataOffset,valueOut) seed = ( seed * a + c ) Mod m dataOffset = dataOffset + 4 ' Only used for the GUI example >>>>> If MilliSecs()-pollTimer > 50 UpdateProgBar(progressBar,Float(dataOffset-dataHeader)/Float(BankSize(dataIn))) PollSystem() pollTimer = MilliSecs() EndIf ' <<<<< Only used for the GUI example Wend Return dataOut End Function '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Function LCG32Decipher:TBank(dataIn:TBank,a:Int=16807,c:Int=2^31-1,m:Int=0,seed:Int=0) Local pollTimer:Int = MilliSecs() ' <<<<< Only used for the GUI example, remove if necessary Local dataHeader:Int Local dataOffset:Int Local dataSize:Int = PeekInt(dataIn,dataOffset) dataOffset = dataOffset + 4 If dataSize < 0 Then Return CreateBank(0) Local dataOut:TBank = CreateBank(dataSize) If dataSize Mod 4 > 0 Then ResizeBank(dataOut,BankSize(dataOut) + 4-(dataSize Mod 4)) If seed = 0 seed = PeekInt(dataIn,dataOffset) dataOffset = dataOffset + 4 EndIf dataHeader = dataOffset While dataOffset < BankSize(dataIn) If dataOffset-dataHeader > BankSize(dataOut) Then Return CreateBank(0) Local valueIn:Int = PeekInt(dataIn,dataOffset) Local valueOut:Int = valueIn~seed ' XOR PokeInt(dataOut,dataOffset-dataHeader,valueOut) seed = ( seed * a + c ) Mod m dataOffset = dataOffset + 4 ' Only used for the GUI example >>>>> If MilliSecs()-pollTimer > 50 UpdateProgBar(progressBar,Float(dataOffset)/Float(BankSize(dataIn))) PollSystem() pollTimer = MilliSecs() EndIf ' <<<<< Only used for the GUI example Wend ResizeBank(dataOut,dataSize) Return dataOut End Function |
Comments
None.
Code Archives Forum