There is an OOP style library based on Guimauve's original code, see here PukallCipher - Update V1.1.0
I have stripped the security level to 256 bits (let me know if you are interested with the multiple security level feature).
I'm releasing it in hope it might be useful to some one.
Best regards
StarBootics
Code: Select all
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; AUTOMATICALLY GENERATED CODE, DO NOT MODIFY
; UNLESS YOU REALLY, REALLY, REALLY MEAN IT !!
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Code generated by : Dev-Object - V1.1.0
; Project name : Read Write PukallCipher
; File name : Read Write PukallCipher - OOP.pb
; File Version : 1.0.1
; Programmation : OK
; Programmed by : StarBootics
; Creation Date : October 18th, 2020
; Last update : October 29th, 2020
; Coded for PureBasic : V5.72
; Platform : Windows, Linux, MacOS X
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; This library is meant to be use when security is needed to Read
; and Write a binary file. This is a symetric crypting algorythm
; with 256 bits security level. Based on Guimauve's original code
; see here :
;
; https://www.purebasic.fr/english/viewtopic.php?f=12&t=37733
;
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
DeclareModule PukallCipher
Interface PukallCipher
GetKey.s()
SetKey(P_Key.s)
PC_WriteString(FileID.i, P_String.s)
PC_WriteByte(FileID.i, P_Value.b)
PC_WriteAsciiCharacter(FileID.i, P_Value.a)
PC_WriteWord(FileID.i, P_Value.w)
PC_WriteUnicodeCharacter(FileID.i, P_Value.u)
PC_WriteCharacter(FileID.i, P_Value.c)
PC_WriteLong(FileID.i, P_Value.l)
PC_WriteQuad(FileID.i, P_Value.q)
PC_WriteInteger(FileID.i, P_Value.i)
PC_WriteFloat(FileID.i, P_Value.f)
PC_WriteDouble(FileID.i, P_Value.d)
PC_ReadString.s(FileID.i)
PC_ReadByte.b(FileID.i)
PC_ReadAsciiCharacter.a(FileID.i)
PC_ReadWord.w(FileID.i)
PC_ReadUnicodeCharacter.u(FileID.i)
PC_ReadCharacter.c(FileID.i)
PC_ReadLong.l(FileID.i)
PC_ReadQuad.q(FileID.i)
PC_ReadInteger.i(FileID.i)
PC_ReadFloat.f(FileID.i)
PC_ReadDouble.d(FileID.i)
Free()
EndInterface
Declare.i New(P_Key.s = "PukallCipher")
EndDeclareModule
Module PukallCipher
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Sizing Constants <<<<<
#PUKALLCIPHER_X1A0_MAX = 16
#PUKALLCIPHER_CLE_MAX = 32
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Structures declaration <<<<<
Structure Private_Members
VirtualTable.i
Key.s
EndStructure
Structure Cipher
Ax.l
Bx.l
Cx.l
Dx.l
Sx.l
X1A2.l
Res.l
Counter.l
Inter.l
X1A0.l[#PUKALLCIPHER_X1A0_MAX]
Cle.c[#PUKALLCIPHER_CLE_MAX]
StringLength.l
Char.c
Rep.c
Dxx.c
Exx.c
Cfc.l
Cfd.l
EndStructure
Macro Private_Code(CipherA)
CipherA\Dx = CipherA\X1A2 + CipherA\Counter
CipherA\Ax = CipherA\X1A0[CipherA\Counter]
CipherA\Bx = $015A
CipherA\Cx = $4E35
Swap CipherA\Ax, CipherA\Sx
Swap CipherA\Ax, CipherA\Dx
If CipherA\Ax <> 0
CipherA\Ax = CipherA\Ax * CipherA\Bx
EndIf
Swap CipherA\Ax, CipherA\Cx
If CipherA\Ax <> 0
CipherA\Ax = CipherA\Ax * CipherA\Sx
CipherA\Ax = CipherA\Ax + CipherA\Cx
EndIf
Swap CipherA\Ax, CipherA\Sx
CipherA\Ax = CipherA\Ax * CipherA\Bx
CipherA\Dx = CipherA\Cx + CipherA\Dx
CipherA\Ax = CipherA\Ax + 1
CipherA\X1A2 = CipherA\Dx
CipherA\X1A0[CipherA\Counter] = CipherA\Ax
CipherA\Counter = CipherA\Counter + 1
CipherA\Res = CipherA\Ax ! CipherA\Dx
EndMacro
Macro Private_Assemble(CipherA)
CipherA\X1A0[0] = CipherA\Cle[0] * 256 + CipherA\Cle[1]
Private_Code(CipherA)
CipherA\Inter = CipherA\Res
KeyIndex = 2
For Index = 1 To #PUKALLCIPHER_X1A0_MAX - 1
CipherA\X1A0[Index] = CipherA\X1A0[Index-1] ! CipherA\Cle[KeyIndex] * 256 + CipherA\Cle[KeyIndex+1]
Private_Code(CipherA)
CipherA\Inter = CipherA\Inter ! CipherA\Res
KeyIndex + 2
Next
CipherA\Counter = 0
EndMacro
; <<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The Gettors <<<<<
Procedure.s GetKey(*This.Private_Members)
ProcedureReturn *This\Key
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The Settors <<<<<
Procedure SetKey(*This.Private_Members, P_Key.s)
If P_Key <> ""
*This\Key = P_Key
Else
*This\Key = "PukallCipher"
EndIf
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Write on binary file instructions <<<<<
Procedure PC_WriteString(*This.Private_Members, FileID.i, P_String.s)
Cipher.Cipher
UseMD5Fingerprint()
NormKey.s = StringFingerprint(*This\Key, #PB_Cipher_MD5)
For KeyIndex = 0 To #PUKALLCIPHER_CLE_MAX - 1
Cipher\Cle[KeyIndex] = Asc(Mid(NormKey, KeyIndex + 1, 1))
Next
Cipher\Sx = 0
Cipher\X1A2 = 0
Cipher\Counter = 0
Cipher\StringLength = Len(P_String) - 1
WriteLong(FileID, Cipher\StringLength)
For BufferIndex = 0 To Cipher\StringLength
Cipher\Char = Asc(Mid(P_String, BufferIndex + 1,1))
Private_Assemble(Cipher)
Cipher\Cfc = Cipher\Inter >> 8
Cipher\Cfd = Cipher\Inter & 255
For KeyIndex = 0 To #PUKALLCIPHER_CLE_MAX - 1
Cipher\Cle[KeyIndex] = Cipher\Cle[KeyIndex] ! Cipher\Char
Next
Cipher\Char = Cipher\Char ! (Cipher\Cfc ! Cipher\Cfd)
Cipher\Dxx = Cipher\Char >> 4
Cipher\Exx = Cipher\Char & 15
WriteCharacter(FileID, $61 + Cipher\Dxx)
WriteCharacter(FileID, $61 + Cipher\Exx)
Next
EndProcedure
Procedure PC_WriteByte(*This.Private_Members, FileID.i, P_Value.b)
If P_Value < 0
Sign.s = "-"
P_Value = P_Value * -1
EndIf
PC_WriteString(*This, FileID, Sign + RSet(Str(P_Value), 6, "0"))
EndProcedure
Procedure PC_WriteAsciiCharacter(*This.Private_Members, FileID.i, P_Value.a)
PC_WriteString(*This, FileID, RSet(Str(P_Value), 6, "0"))
EndProcedure
Procedure PC_WriteWord(*This.Private_Members, FileID.i, P_Value.w)
If P_Value < 0
Sign.s = "-"
P_Value = P_Value * -1
EndIf
PC_WriteString(*This, FileID, Sign + RSet(Str(P_Value), 10, "0"))
EndProcedure
Procedure PC_WriteUnicodeCharacter(*This.Private_Members, FileID.i, P_Value.u)
PC_WriteString(*This, FileID, RSet(Str(P_Value), 10, "0"))
EndProcedure
Procedure PC_WriteCharacter(*This.Private_Members, FileID.i, P_Value.c)
PC_WriteString(*This, FileID, RSet(Str(P_Value), 10, "0"))
EndProcedure
Procedure PC_WriteLong(*This.Private_Members, FileID.i, P_Value.l)
If P_Value < 0
Sign.s = "-"
P_Value = P_Value * -1
EndIf
PC_WriteString(*This, FileID, Sign + RSet(Str(P_Value), 22, "0"))
EndProcedure
Procedure PC_WriteQuad(*This.Private_Members, FileID.i, P_Value.q)
If P_Value < 0
Sign.s = "-"
P_Value = P_Value * -1
EndIf
PC_WriteString(*This, FileID, Sign + RSet(Str(P_Value), 42, "0"))
EndProcedure
Procedure PC_WriteInteger(*This.Private_Members, FileID.i, P_Value.i)
If P_Value < 0
Sign.s = "-"
P_Value = P_Value * -1
EndIf
PC_WriteString(*This, FileID, Sign + RSet(Str(P_Value), 42, "0"))
EndProcedure
Procedure PC_WriteFloat(*This.Private_Members, FileID.i, P_Value.f)
PC_WriteString(*This, FileID, StrF(P_Value, 14))
EndProcedure
Procedure PC_WriteDouble(*This.Private_Members, FileID.i, P_Value.d)
PC_WriteString(*This, FileID, StrD(P_Value, 25))
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Read on binary file instructions <<<<<
Procedure.s PC_ReadString(*This.Private_Members, FileID.i)
Cipher.Cipher
UseMD5Fingerprint()
NormKey.s = StringFingerprint(*This\Key, #PB_Cipher_MD5)
For KeyIndex = 0 To #PUKALLCIPHER_CLE_MAX - 1
Cipher\Cle[KeyIndex] = Asc(Mid(NormKey, KeyIndex + 1,1))
Next
Cipher\Sx = 0
Cipher\X1A2 = 0
Cipher\Counter = 0
Cipher\StringLength = ReadLong(FileID)
For BufferIndex = 0 To Cipher\StringLength
Cipher\Rep = ReadCharacter(FileID)
Cipher\Dxx = (Cipher\Rep - $61) << 4
Cipher\Rep = ReadCharacter(FileID)
Cipher\Exx = Cipher\Rep - $61
Cipher\Char = Cipher\Dxx + Cipher\Exx
Private_Assemble(Cipher)
Cipher\Cfc = Cipher\Inter >> 8
Cipher\Cfd = Cipher\Inter & 255
Cipher\Char = Cipher\Char ! (Cipher\Cfc ! Cipher\Cfd)
For KeyIndex = 0 To #PUKALLCIPHER_CLE_MAX - 1
Cipher\Cle[KeyIndex] = Cipher\Cle[KeyIndex] ! Cipher\Char
Next
DecryptedString.s + Chr(Cipher\Char)
Next
ProcedureReturn DecryptedString
EndProcedure
Procedure.b PC_ReadByte(*This.Private_Members, FileID.i)
ProcedureReturn Val(PC_ReadString(*This, FileID))
EndProcedure
Procedure.a PC_ReadAsciiCharacter(*This.Private_Members, FileID.i)
ProcedureReturn Val(PC_ReadString(*This, FileID))
EndProcedure
Procedure.w PC_ReadWord(*This.Private_Members, FileID.i)
ProcedureReturn Val(PC_ReadString(*This, FileID))
EndProcedure
Procedure.u PC_ReadUnicodeCharacter(*This.Private_Members, FileID.i)
ProcedureReturn Val(PC_ReadString(*This, FileID))
EndProcedure
Procedure.c PC_ReadCharacter(*This.Private_Members, FileID.i)
ProcedureReturn Val(PC_ReadString(*This, FileID))
EndProcedure
Procedure.l PC_ReadLong(*This.Private_Members, FileID.i)
ProcedureReturn Val(PC_ReadString(*This, FileID))
EndProcedure
Procedure.q PC_ReadQuad(*This.Private_Members, FileID.i)
ProcedureReturn Val(PC_ReadString(*This, FileID))
EndProcedure
Procedure.i PC_ReadInteger(*This.Private_Members, FileID.i)
ProcedureReturn Val(PC_ReadString(*This, FileID))
EndProcedure
Procedure.f PC_ReadFloat(*This.Private_Members, FileID.i)
ProcedureReturn ValF(PC_ReadString(*This, FileID))
EndProcedure
Procedure.d PC_ReadDouble(*This.Private_Members, FileID.i)
ProcedureReturn ValD(PC_ReadString(*This, FileID))
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The destructor <<<<<
Procedure Free(*This.Private_Members)
FreeStructure(*This)
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The Constructor <<<<<
Procedure.i New(P_Key.s = "PukallCipher")
*This.Private_Members = AllocateStructure(Private_Members)
*This\VirtualTable = ?START_METHODS
SetKey(*This, P_Key)
ProcedureReturn *This
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Entries of the virtual table <<<<<
DataSection
START_METHODS:
Data.i @GetKey()
Data.i @SetKey()
Data.i @PC_WriteString()
Data.i @PC_WriteByte()
Data.i @PC_WriteAsciiCharacter()
Data.i @PC_WriteWord()
Data.i @PC_WriteUnicodeCharacter()
Data.i @PC_WriteCharacter()
Data.i @PC_WriteLong()
Data.i @PC_WriteQuad()
Data.i @PC_WriteInteger()
Data.i @PC_WriteFloat()
Data.i @PC_WriteDouble()
Data.i @PC_ReadString()
Data.i @PC_ReadByte()
Data.i @PC_ReadAsciiCharacter()
Data.i @PC_ReadWord()
Data.i @PC_ReadUnicodeCharacter()
Data.i @PC_ReadCharacter()
Data.i @PC_ReadLong()
Data.i @PC_ReadQuad()
Data.i @PC_ReadInteger()
Data.i @PC_ReadFloat()
Data.i @PC_ReadDouble()
Data.i @Free()
END_METHODS:
EndDataSection
EndModule
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Code generated in : 00.001 seconds (87000.00 lines/second) <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
CompilerIf #PB_Compiler_IsMainFile
PC.PukallCipher::PukallCipher = PukallCipher::New()
Varw.w = 32700
Varl.l = -2147483645
Varq.q = 9223372036854775800
Varf.f = 2 * #PI
Vard.d = 3 * #PI
Text.s = "J'aime les déesses nordiques super sexy !"
Debug "; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
Debug "; Test on file "
Debug ""
Debug "Original data : "
Debug Varw
Debug Varl
Debug Varq
Debug Varf
Debug Vard
Debug Text
Debug ""
If CreateFile(0, "Test.pc")
PC\SetKey("PureBasic 5.72")
PC\PC_WriteWord(0, Varw)
PC\PC_WriteLong(0, Varl)
PC\PC_WriteQuad(0, Varq)
PC\SetKey("")
PC\PC_WriteFloat(0, Varf)
PC\PC_WriteDouble(0, Vard)
PC\PC_WriteString(0, Text)
CloseFile(0)
EndIf
Debug "Data from the file : "
If ReadFile(1, "Test.pc")
PC\SetKey("PureBasic 5.72")
Debug PC\PC_ReadWord(1)
Debug PC\PC_ReadLong(1)
Debug PC\PC_ReadQuad(1)
PC\SetKey("")
Debug PC\PC_ReadFloat(1)
Debug PC\PC_ReadDouble(1)
Debug PC\PC_ReadString(1)
CloseFile(1)
DeleteFile("Test.pc")
EndIf
PC\Free()
CompilerEndIf
; <<<<<<<<<<<<<<<<<<<<<<<
; <<<<< END OF FILE <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<