Δευτέρα 21 Φεβρουαρίου 2011

Encryption and Byte[] manipulation.

encoding - decoding routine written in GAMBAS

Published under the Creative Commons Attribution-ShareAlike (CC-BY-SA) 3.0 license.


PRIVATE SUB encodedecode(whichFileIn AS String, whichFileOut AS String, whichCode AS Integer, OPTIONAL howmanybits AS Integer = 8, OPTIONAL frombit AS Integer = 0) AS Integer
'only deals with files of size up to 2.147.483.647-(whichcode+howmanybits+1) bytes
'change all declarations to "Long" if you want bigger files or "codes"
'And is memory depended because it loads all of the file to memory.
'(No check is done here)
'There is a cryptographic "leak" to consider:
'In every group of "howmanybits" bytes the first byte
'is decreased in every turn.
DIM PRERROROPENINFILE AS Integer = -1
DIM PRERRORRESIZINGARRAY AS Integer = -2
DIM PRERRORREADINFILE AS Integer = -3
DIM PRERRORKILLINGOUTFILE AS Integer = -4
DIM PRERROROPENOUTFILE AS Integer = -5
DIM PRERRORWRITEOUTFILE AS Integer = -6
DIM PRERROROPT1 AS Integer = -7
DIM PRERROROPT2 AS Integer = -8
DIM PRERROROPT1OR2 AS Integer = -9

DIM xcounter AS Integer 'using a temporary counter for small "FOR..NEXT"s
DIM prhFileIn AS File 'holds "file in" handle
DIM prhFileOut AS File 'holds "file out" handle
DIM prhBytesIn AS NEW Byte[] 'holds content of file in handle
DIM prhBitCollection AS NEW Integer[] 'a "collection" of bit potisions
DIM prhCode AS Integer 'holds a number for decrementing "code"
DIM prhTemp8 AS Integer 'holds a temporary index to "collection" of bit positions
DIM prhBitToXOR AS Integer 'holds the actual bit position to "XOR"
'We can use prhCode and find which byte to change
'but I think that will decrease the speed
DIM prhByteToChangeCounter AS Integer

IF howmanybits > 8 OR howmanybits < 1 THEN
'debuging:Message.Error("Bits must be from 1 to 8")
RETURN PRERROROPT1
END IF
IF frombit < 0 THEN
'debuging:Message.Error("frombits must be >=0")
RETURN PRERROROPT2
END IF
IF howmanybits + frombit > 8 THEN
'debuging:Message.Error("howmanybits + frombit must be <=8")
RETURN PRERROROPT1OR2
END IF

TRY prhFileIn = OPEN whichFileIn FOR READ
IF ERROR THEN
'debuging:Message.Error("Unable to open the 'IN' file")
RETURN PRERROROPENINFILE
END IF
'resize the byte array which will hold the in values
TRY prhBytesIn.Resize(Lof(prhFileIn))
IF ERROR THEN
'debuging:Message.Error("Unable to resize the array. Maybe not enough memory.")
RETURN PRERRORRESIZINGARRAY
END IF
'this actually reads all bytes in a byte array
TRY prhBytesIn.Read(prhFileIn)
IF ERROR THEN
'debuging:Message.Error("Unable to read the 'IN' file")
RETURN PRERRORREADINFILE
END IF
CLOSE prhFileIn
'create a "code" based on byte array size and number given from user
prhCode = whichCode + prhBytesIn.Max
'add bits of one "howmanybits" plus one so that, at the end,
'we allways have a number greater then howmanybits
'even if user gave as code 0 (zero)
prhCode += howmanybits + 1
'add as many bytes as groups of "howmanybits" bytes exists in source
prhCode += Int(prhCode / howmanybits) + 1 'added
'set the counter of bytes changed to zero
prhByteToChangeCounter = 0
'initialize the "collection" of bit positions
FOR xcounter = 0 TO howmanybits - 1
prhBitCollection.Add(xcounter)
NEXT
DO
'if we have changed all bytes then exit loop
IF prhByteToChangeCounter > prhBytesIn.Max THEN BREAK
'find which of the remaining "positions" of bits we must change
prhTemp8 = prhCode MOD (prhBitCollection.Max + 1)
'find which bit to xor from the "collection"
prhBitToXOR = prhBitCollection[prhTemp8]
'debuging:
TextArea1.Text &= prhBitToXOR
'remove that position from the collection
prhBitCollection.Remove(prhTemp8)
'"xor" the n'th position (=prhBitToXOR)
prhBytesIn[prhByteToChangeCounter] = BChg(prhBytesIn[prhByteToChangeCounter], prhBitToXOR + frombit)
'decrease "code"
DEC prhCode
IF prhBitCollection.Count < 1 THEN
'"reinitialize" the "collection" of bits
'debuging:TextArea1.Text &= "\n"
FOR xcounter = 0 TO howmanybits - 1
prhBitCollection.Add(xcounter)
NEXT
DEC prhCode 'added
END IF
'increease the counter of bytes changed
INC prhByteToChangeCounter
LOOP

IF Exist(whichFileOut) THEN
TRY KILL whichFileOut
IF ERROR THEN
'debuging:Message.Error("Unable to kill the "OUT" file")
RETURN PRERRORKILLINGOUTFILE
END IF
END IF
TRY prhFileOut = OPEN whichFileOut FOR CREATE 'WRITE 'CREATE
IF ERROR THEN
'debuging:Message.Error("Unable to open the "OUT" file")
RETURN PRERROROPENOUTFILE
END IF

TRY prhBytesIn.Write(prhFileOut)
IF ERROR THEN
'debuging:Message.Error("Unable to write to the "OUT" file")
RETURN PRERRORWRITEOUTFILE
END IF
CLOSE prhFileOut
RETURN prhBytesIn.Count
END

PUBLIC SUB sampleusageENcodefile()
DIM prhReturnedVar as Integer
prhReturnedVar=encodedecode("original.jpg", "encoded.notajpg", 12345)
IF prhReturnedVar<0 THEN
'an error occured
'do something here
'debuging:Message.Error("Unable to write to the "OUT" file")
ELSE
'no error occured
'
END IF
END

PUBLIC SUB sampleusageDEcodefile()
DIM prhReturnedVar as Integer
prhReturnedVar=encodedecode( "encoded.notajpg", "decoded.jpg", 12345)
END