example of trivial text encoding/decoding for ascii strings

Share your advanced PureBasic knowledge/code with the community.
Bo Marchais
User
User
Posts: 61
Joined: Sun Apr 03, 2016 12:03 am

example of trivial text encoding/decoding for ascii strings

Post by Bo Marchais »

I am sure this has been written 10,000 times before but...

Purebasic exposes your text strings to anyone who wishes to open your .exe in an editor such as notepad++ or a hex editor.

Sometimes we don't want people to see what strings are present in our program.
Eventually most professionals use an outside tool to compile local strings into data,
then decompress/decode them at runtime. For everyone else, I present some trivial
encoding and decoding examples.

hmmmm....
It wouldn't be difficult to have the compiler do the encoding for you in a
manner that encodes your strings when compiling, and then at runtime
decodes them (during a string assignment)...

as in:
f$ = "error message that you cannot hide" <--- what you see is what you get
vs.
f$ = obfuscate("error message you dont want to expose") <---encoded at compile, decoded at run

I think maybe it's a useful trick with more applications...

Anyway, here is an example of simple rolling encryption on ascii text.
Once you've encoded the text, you can cut and paste and assign it to a variable,
so that it is hidden in plain sight but also easily decoded at run time.

2016-04-08 : Edited to show examples of procedures for this. The learner version is still below...

Code: Select all

		Procedure.s		rc_encode(string$,salt)
			For i = 1 To Len(string$)
				encoded$ + Right("00"+UCase(Hex(Asc(Mid(string$,i,1)) ! ((salt+i)%256),#PB_Byte)),2)
			Next
			ProcedureReturn	encoded$	
		EndProcedure
		
		
		Procedure.s		rc_decode(string$,salt)
			For i = 1 To (Len(string$)/2)
				ptr = ((i-1)*2)+1 : decoded$ + Chr(Val("$"+Mid(string$,ptr,2)) ! ((salt+i)%256))							
			Next
			ProcedureReturn	decoded$	
		EndProcedure

# example of usage - just cut and paste to see how it works

		salt = 65342		; can be any int from 0-65535
		input$ = "It might be useful..."
		 junk$ = rc_encode(input$,salt)
		output$ = rc_decode(junk$,salt) 
		Debug "SOURCE: "+input$
		Debug "CIPHER: "+junk$
		Debug "OUTPUT: "+output$
		
----

The code is just a way to illustrate the concept. You could also use this to save strings to disk,
or to send them in plaintext via email, web or network transfer. Enjoy!

Warning: This is not crypto... it's just a way to make plain text not so plain. It's not suitable for important data.
This is VERY vulnerable to anyone with even basic crypto knowledge or even if they've heard of Alan Turing.
ALL it does is hide plain text in plain sight!

Code: Select all

string$ = "I am just a simple test of an inefficient algorithm on a string with an embedded CR inside! "+Chr(13)+"Yes, a test!"

Debug "Let's get started!"
Debug "Text to encode. Notice that the example has two lines..."
Debug "---"
Debug string$
Debug "---"

; ---- begin encoding

		salt = 21762										; should be a hash but 0-65535 is fine
		strlen = Len(string$)
		charcount = 0
                output$=""
		For i = 1 To strlen									; this is just an example - we don't care
			                                 							; what the internal representation is. 
			ab$ = Mid(string$,charcount,1)						; use word instead of bytes for unicode
			a.b = Asc(ab$)
			b.b = ((salt+i) % 256) 								; weak salt makes it harder to decode
			c = a ! b										; (in assembly language this is trivial!)
			d$ = Right("00"+UCase(Hex(c,#PB_Byte )),2)
			output$ + d$
		Next
	
; ---- all done encoding
		
		Debug "encodng "+Str(strlen)+" chars with rolling XOR encryption and a weak salt."
		
		Debug "--------"
		Debug "Here's what comes out. This is what would be "
		Debug "seen by a user poking around in the .exe: "
		Debug makeitpretty(output$)+Chr(13)
		Debug "--------"
		
		string$ = output$										; copy encoded string into input
		output$ = "";										; and reset output
		
		; ---- let's decode	this
		
		strlen = Int((Len(string$)+1)/2)
		charcount = 0
		For i = 0 To strlen									; reverse the process
												
			pos = 1 + (i*2)
			ab$ = "$"+Mid(string$,pos,2)							; word instead of bytes for unicode
			a.b = Val(ab$)
			b.b = ((salt+i+1) % 256)	 						; n % 65536	for unicode. 
			c = a ! b
			output$ + Chr(c)
		Next
; ---- all done decoding
		
		Debug "This is the decoded output, ready for use!:"
		Debug output$
		
		
Last edited by Bo Marchais on Fri Apr 08, 2016 11:12 pm, edited 1 time in total.
User avatar
idle
Always Here
Always Here
Posts: 5870
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: example of trivial text encoding/decoding for ascii stri

Post by idle »

here's a slightly reduced version for you to look over

[edited] to what keya said

Code: Select all


Procedure EncDec(*string,len,salt) 
  Protected *char.ascii
  *char = *string 
  For i = 1 To len                           
    *char\a ! ((salt+i) % 256) 
    *char+1
  Next
EndProcedure 
  

string$ = "I am just a simple test of an inefficient algorithm on a string with an embedded CR inside! "+Chr(13)+"Yes, a test!"

salt = 21762                             
strlen = StringByteLength(string$)

EncDec(@string$,strlen,salt) 

Debug string$ 

EncDec(@string$,strlen,salt)

Debug string$ 

Windows 11, Manjaro, Raspberry Pi OS
Image
User avatar
Keya
Addict
Addict
Posts: 1890
Joined: Thu Jun 04, 2015 7:10 am

Re: example of trivial text encoding/decoding for ascii stri

Post by Keya »

change "Protected *char.char" to "Protected *char.Ascii" and you can get rid of the Structure :D
User avatar
idle
Always Here
Always Here
Posts: 5870
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: example of trivial text encoding/decoding for ascii stri

Post by idle »

I posted to quick, this is what I meant

Code: Select all

Structure char 
  a.a[0]
EndStructure   

Procedure EncDec(*string,len,salt) 
  Protected *char.char 
  *char = *string 
  For i = 0 To len-1                           
    *char\a[i] ! ((salt+i) % 256) 
  Next
EndProcedure 
  

string$ = "I am just a simple test of an inefficient algorithm on a string with an embedded CR inside! "+Chr(13)+"Yes, a test!"
salt = 21762                             
strlen = StringByteLength(string$)

EncDec(@string$,strlen,salt) 
Debug string$ 

EncDec(@string$,strlen,salt)
Debug string$ 

Windows 11, Manjaro, Raspberry Pi OS
Image
Bo Marchais
User
User
Posts: 61
Joined: Sun Apr 03, 2016 12:03 am

Re: example of trivial text encoding/decoding for ascii stri

Post by Bo Marchais »

yowza!
My examples were optimized for newbies - and are subtly different from yours.

I added the ascii hex conversions on purpose so that the data path could be
treated as ordinary ASCII text - it might not be 8 bit clean from start to stop.
But as far as rolling xor cipher inverters go... that's some amazingly sexy code!
Well done! Code golf in PB... oh yeah!
Marc56us
Addict
Addict
Posts: 1600
Joined: Sat Feb 08, 2014 3:26 pm

Re: example of trivial text encoding/decoding for ascii stri

Post by Marc56us »

Not very secure, but fast (to mislead newbies), internal function: ReverseString()

Code: Select all

; Debug ReverseString("I am just a simple test of an inefficient algorithm on a string With an embedded CR inside! "+Chr(13)+"Yes, a test!")
In code

Code: Select all

Hello.s = ReverseString("tset a ,seY"+Chr(13)+" !edisni RC deddebme na htiW gnirts a no mhtirogla tneiciffeni na fo tset elpmis a tsuj ma I")

MessageRequester("Hello", Hello)
Avoid using '$' for strings still prefer '.s' to complicate hexa search.

:wink:
User avatar
Keya
Addict
Addict
Posts: 1890
Joined: Thu Jun 04, 2015 7:10 am

Re: example of trivial text encoding/decoding for ascii stri

Post by Keya »

Marc56us wrote:Avoid using '$' for strings still prefer '.s' to complicate hexa search.
:wink:
can you elaborate please? the following code:

Code: Select all

test1.s = "APPLE"
test2$ = "ORANGE"
doesn't complicate a hex search:
Image

no comment on ReverseString() :)
Bo Marchais
User
User
Posts: 61
Joined: Sun Apr 03, 2016 12:03 am

Re: example of trivial text encoding/decoding for ascii stri

Post by Bo Marchais »

Yes, reversing a string doesn't work - human brains are just too clever at
spotting patterns.
Lots of bright people think to open an .exe in a text editor or hex editor.

This works very well to let you bury random text. It's not good enough to
hide cc data or secrets, but it'll keep your little sister out of your to do list.
It is only a cipher, and not crpto.

Did I mention you can encode or decode 2 or 3 times? And that text files
zip or compress really well? And that you can use the encode function to
turn binary data to text? Or you can zip data, then encode the zip... all
quite pointless from a real crypto standpoint, but it'll probably slow down
anybody who isn't very good at math.

Now... if that salt was to get jiggy, or you added a 3rd or 4th term to
the xor... well, to quote my favorite waiter: that's a story for another time.
But never forget - debuggers reveal secrets. Create your salt at runtime
and make it unique if you're building a game or something... otherwise the
other kids will figure out your cheat codes. And then where will you be?
walbus
Addict
Addict
Posts: 929
Joined: Sat Mar 02, 2013 9:17 am

Re: example of trivial text encoding/decoding for ascii stri

Post by walbus »

Or so :

But, this are all very bad ideas :idea: LOL

Code: Select all


Structure char : a.a[0] : EndStructure 

Procedure EncDec(*string.char,len,salt) 
  For i = 0 To len-1 : *string\a[i] ! ((salt+i) % 256) : Next
EndProcedure 
  
string$ = "I am just a simple test of an inefficient algorithm on a string with an embedded CR inside! "+Chr(13)+"Yes, a test!"
salt = 21762                             
strlen = StringByteLength(string$)

EncDec(@string$,strlen,salt) 
Debug string$ 

EncDec(@string$,strlen,salt)
Debug string$ 
User avatar
Keya
Addict
Addict
Posts: 1890
Joined: Thu Jun 04, 2015 7:10 am

Re: example of trivial text encoding/decoding for ascii stri

Post by Keya »

with a lot of these types of encodings it seems there's only 255 possible decodings, i think it would be cool to achieve 32bit possible decodings, if it can still be kept as simple of course :) (and can that still be accomplished one byte at a time or would it have to require operating on 32bits at a time and therefore have undesired boundary or padding requirements?)
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: example of trivial text encoding/decoding for ascii stri

Post by wilbert »

If you want to keep the result a string, it's important that no zero character is generated as result of the encoding.
The whole idea of 32 bits, is to make things faster by processing 32 bits at a time.
If you want to make it more complicated, you can xor the data against the output of a pseudo random generator (or add / sub instead of xor).
Windows (x64)
Raspberry Pi OS (Arm64)
walbus
Addict
Addict
Posts: 929
Joined: Sat Mar 02, 2013 9:17 am

Re: example of trivial text encoding/decoding for ascii stri

Post by walbus »

False or missing termination is a trap and can make many nasty bugs.
A other thing is, PB supporting in the future only Unicode.
It is very important to learning and making string handling all over in Unicode.
Last edited by walbus on Sun Apr 10, 2016 9:28 am, edited 1 time in total.
Bo Marchais
User
User
Posts: 61
Joined: Sun Apr 03, 2016 12:03 am

Re: example of trivial text encoding/decoding for ascii stri

Post by Bo Marchais »

Nah, modern chars sets are easy and will just make the encoded data larger.
It's easy to change this to use words instead of bytes, just see the learner version and change the .b to .w
and change the modulo to 65536 from 256.

Everyone keeps missing that while xor alone works great, the actual application requires conversion into hex
so that the data can be embedded as ordinary string data. You can use base36 or base64(using upper,lower,
nums and punctuation) to slightly decrease the message size using 3 chars instead of 4 PLUS you get the
ability to encode/decode escape sequences or out of band information.

This is still not safe for real crypto purposes. However, it's great fun to use base64 and alter your encodings
(salt/key/whatever) on the fly using escape sequences. One weakness is that character sets are not really
very hard to spot, even in a rolling cipher. This kind of thing is pretty similar to a simple enigma box and can
often be decoded using only paper and pencil. You have to add a lot of rotors and move them on the fly to
slow anyone down...and again, anyone with access to the .exe can undo your clever scheme.

The problem is that no matter how smart you are, there are smarter people out there somewhere.
Hopefully your customers won't be interested enough to waste even a few hours to undo your work.
Security is a rabbit hole and it goes a long way down. I don't lose sleep worrying about it. My rule is:
if it costs more to reverse it than ~70% of the product cost, no one will bother unless it's a game or
your program is really popular!
walbus
Addict
Addict
Posts: 929
Joined: Sat Mar 02, 2013 9:17 am

Re: example of trivial text encoding/decoding for ascii stri

Post by walbus »

Basexx make the strings longer !
So you must ever use padding for encoding and decoding !

You must also ever use padding with Basexx,
Then you can use many better a very good block chiffre,
Last edited by walbus on Sun Apr 10, 2016 9:30 am, edited 2 times in total.
User avatar
heartbone
Addict
Addict
Posts: 1058
Joined: Fri Apr 12, 2013 1:55 pm
Location: just outside of Ferguson

Re: example of trivial text encoding/decoding for ascii stri

Post by heartbone »

Thanks for this thread and its code contributors. :thumbs up:
Keep it BASIC.
Post Reply