Encrypt and Unencrypt a text file

BlitzMax Forums/BlitzMax Beginners Area/Encrypt and Unencrypt a text file

Takis76(Posted 2013) [#1]
Hello my friends,
I am looking some idea how to encrypt one text file.

I have my level editor which generates the game adventure which saved and is readable and the player can cheat the adventure.

The file contents are similar to .ini file contents and you easily able to read the contents (I want the adventure file created my the level editor be easy readable) to able to make easy changes in the exported game adventure, during the construction of the adventure only.

But when you have finish and want to distribute your adventure with the game you don't want your adventure be readable because the (Players cheaters) when they will stuck playing your adventure created from the level editor easily will change the map, or remove some door or add some item.

So is it possible to encrypt my exported adventure.txt file and then when my editor will load the adventure will unencrypt the file (Back to its original readable format) will load the adventure and then will delete the the unencrypted file, but the adventure will be loaded in the memory and the player will play the game and there will not be any unencrypted file because the file will be delete after load.
Also if is possible to use some key encryption code will be very nice. So the cheater will must know the key to unencrypt the file.
Also need to know which was the encryption algorithm.

Sure players will not bother to unencrypt and cheat the adventure then.

The file is a plain text file like:

[PARTY ENTRY]
Party start level:01
Party start map x:01
Party start map y:01
Party start direction:EAST

[LEVEL01]
Level Description:Level Discription
02020202.01010101.02020202.01010101.02020202.01010101.02020202.01010101.02020202.01010101.02020202.01010101.02020202.01010101.02020202.01010101.02020202.01010101.02020202.01010101.02020202.01010101.02020202.01010101.02020202.01010101.02020202.01010101.02020202.01010101.02020202.01010101.02020202.01010101.02020202.01010101.02020202.01010101.02020202.01010101.02020202.01010101.
01010101.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.02020202.
02020202.00000000.02020202.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.01010101.
01010101.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.02020202.
02020202.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.01010101.
01010101.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.02020202.
02020202.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.01010101.
.
.
.

[DOORS]
blah blah


I use WriteFile("adventure.txt")
WriteString(my_file, "Party start direction:NORTH")
and
WriteLine(my_file,"")
commands to save my adventure.
My length of lines are more than 256 characters long.
And I use ReadString() and ReadLine() commands to load the data back to viariables

Any easy idea? (Thank you very much). :)


Henri(Posted 2013) [#2]
Hello,

there was similar discussion in this thread.


-Henri


Takis76(Posted 2013) [#3]
Yes I saw this one, but I haven't understood how is working and I manage to encrypt and decrypt my text file, but I after decrypting there are garbage at the end of the file.
Also after decrypting the file loses all line return chr(13) at the end of each line and I see the file as row.

[PARTY ENTRY]Party start level:01Party start map x:01Party start map y:01Party startdirection:EAST

Do you know how to fix the line return at the end of each line and how to remove the garbage at the end of the file?


Takis76(Posted 2013) [#4]
I found another one nice code and it seems my problem was solved.

The example with the text file in original exported format from the level editor.
Creates another one text file the encrypted one which is scrambled.
And the load the scrambled file back to the original.

Global encryption_key:String = "some key"

Local Bank:TBank = Cipher.Encrypt(LoadBank("adventure.txt"), "some key")
SaveBank(Bank, "encrypted.txt")

Bank = Cipher.Decrypt(LoadBank("encrypted.txt"), "blah")
SaveBank(Bank, "adventure22.txt")




Encryption and Decryption code:

Type Cipher

	Function Encrypt:TBank(Bank:TBank, Key$)
		Local t:Int=10, n:Int, ki:Int
		Local Out:TBank = CreateBank(Bank.Size())
		Local inptr:Byte Ptr = BankBuf(Bank)
		Local outptr:Byte Ptr = BankBuf(Out)
		For n=0 Until key.length
			Select n Mod 2
		 		Case 0 ; t:*key[n]
				Case 1 ; t:+key[n]
			EndSelect
			t:Mod 360
		Next
		For n=0 Until Bank.Size()
			outptr[n]=inptr[n]+Floor(Cos(t)*255)
			t:+(inptr[n]*key[ki])+n
			t:Mod 360+inptr[n]
			ki:+1
			If ki=>key.length ki=0
		Next
		Return Out
	EndFunction

	Function Decrypt:TBank(Bank:TBank, Key$)
		Local t:Int=10, n:Int, ki:Int
		Local Out:TBank = CreateBank(Bank.Size())
		Local inptr:Byte Ptr = BankBuf(Bank)
		Local outptr:Byte Ptr = BankBuf(Out)
		For n=0 Until key.length
			Select n Mod 2
		 		Case 0 ; t:*key[n]
				Case 1 ; t:+key[n]
			EndSelect
			t:Mod 360
		Next
		For n=0 Until Bank.Size()
			outptr[n]=inptr[n]-Floor(Cos(t)*255)
			t:+(outptr[n]*key[ki])+n
			t:Mod 360+outptr[n]
			ki:+1
			If ki=>key.length ki=0
		Next
		Return Out
	EndFunction

EndType





Function RC4:String(inp:String, key:String)
    Local S%[512+Ceil(inp.Length*.55)]
    Local i%, j%, t%, x%
    Local outbuf@@ Ptr = Short Ptr(Varptr s[512])
    
    j = 0
    For i = 0 To 255
        S[i] = i
        If j > (Key.length-1) Then
            j = 0
        EndIf
        S[256+i] = key[j]&$ff
        j:+ 1
    Next
    
    j = 0
    For i = 0 To 255
        j = (j + S[i] + S[256+i]) & $ff
        t = S[i]
        S[i] = S[j]
        S[j] = t
    Next
    
    i = 0
    j = 0
    For x:Int = 0 To inp.Length - 1
        i = (i + 1) & $ff
        j = (j + S[i]) & $ff
        t = S[i]
        S[i] = S[j]
        S[j] = t
        t = (S[i] + S[j]) & $ff
        outbuf[x] = (inp[x] ~ S[t])
    Next
    
    Return String.FromShorts(outbuf, inp.Length)
End Function



Henri(Posted 2013) [#5]
Alright, I modified the original function a bit. Here is a example:




This is a generic way of doing this, but should be easily adapted.

-Henri

EDIT: Seems you where faster by a minute :-)


Takis76(Posted 2013) [#6]
Your second code loaded my file correctly without garbage at the end but there is no return character in each line "~n"

I used the code you have above for RC4 algorithm with the example bellow.
Global my_file1:TStream = ReadFile("adventure.txt")
Global my_encrypted:String, my_decrypted:String
Global my_data1:String
While Not Eof(my_file1)
	my_data1:+ReadLine(my_file1) + "~n"
Wend
CloseStream(my_file1)
'Crypt original text
my_encrypted = RC4(my_data1, "key")
'Save crypted text to file
SaveString(my_encrypted, "crypted.txt")
'Load crypted textfile
my_decrypted = RC4(LoadString("crypted.txt"), "key")
'Save decrypted text to file
SaveString(my_decrypted, "decrypted.txt")


The code worked but the "~n" characters wasn't written after decrypting.
I see continuous row file again.
Also with your code I don't have the encryption and decryption codes separately.
As I understood your code reads the encrypted code and decrypt it automatically.
If the code is not crypted, encrypts and if is it crypted , decrypts.
But never mind.

Why are you using savestring instead of writefile?


Henri(Posted 2013) [#7]
Hello,

the newline character is there even if notepad shows everything in one line (try opening with notepad++ to see).

To show your text correctly in notepad modify this code line:
my_data1:+ReadLine(my_file1) + "~n"

...to this:
my_data1:+ReadLine(my_file1) + "~r~n"

Why are you using savestring instead of writefile?

No particular reason.It just fitted in my example, but you can use what ever fits your needs.

-Henri


Takis76(Posted 2013) [#8]
What is the difference between ~r and ~n
Suppose -n adds a newline.
And -r returns a new line.
Do both return a new line?
Or ~n adding a new line must return it.
If I will put ~r only?

Your code worked. I load my data in notepad and I would like to see them in notepad.
Thank you for correction of the code.
Which lines of codes do the encryption only and which lines do the decryption only?


Henri(Posted 2013) [#9]
What is the difference between ~r and ~n

In historical sense ~r (Carriage return) tell's printer to return printhead back to left side and ~n (new line) tell's printer to anvance paper by one line.
Different systems might implement line break a little bit differently, but in Windows enviroment the standard way is ~r~n in unison and in this order. Of course it's up to viewing software to implement this correctly (usually the ~n is sufficient).

Which lines of codes do the encryption only and which lines do the decryption only?

The way the RC4-function operates it essentially flips the source text. so if the text is crypted then the function decypher's the text and vice versa. You could easily make supporting functions like crypt() and decrypt() and add a marker at the start of your file to signify wether it is crypted or not if you'd like.

-Henri


Takis76(Posted 2013) [#10]
SO every time you run the function flips (Encrypted/Decrypted)

It works and I see the lines correctly with notepad too.

Thank you very much.


BLaBZ(Posted 2013) [#11]
Whoa! Use LoadText() instead of reading it line by line. You'll then have the data exactly how you saved it.