example of trivial text encoding/decoding for ascii strings

Share your advanced PureBasic knowledge/code with the community.
User avatar
StarBootics
Addict
Addict
Posts: 1006
Joined: Sun Jul 07, 2013 11:35 am
Location: Canada

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

Post by StarBootics »

Hello everyone,

As usual, this is a Module version of the original code. My question is : How to make it Unicode Compliant ?

Best regards
StarBootics

Code: Select all

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Project name : RollingEncryption - Module
; File Name : RollingEncryption - Module.pb
; File version: 1.1.0
; Programming : OK
; Programmed by : StarBootics
; Date : 09-04-2016
; Last Update : 09-04-2016
; PureBasic code : V5.42 LTS
; Platform : Windows, Linux, MacOS X
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; This code was originally created by Bo Marchais
;
; I deserve credit only to convert the original 
; code into a Module.
;
; This code is free to be use where ever you like 
; but you use it at your own risk.
;
; The author can in no way be held responsible 
; for data loss, damage or other annoying 
; situations that may occur.
;
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

DeclareModule RollingEncryption

  Declare Initialize(P_Salt.u)
  Declare Reset()
  Declare.s Encode(P_String.s)
  Declare.s Decode(P_String.s)
  
EndDeclareModule

Module RollingEncryption

  Structure Instance

    IsInitialize.b
    Salt.u

  EndStructure

  Global Instance.Instance

  Procedure Initialize(P_Salt.u)
    
    Instance\IsInitialize = #True
    Instance\Salt = P_Salt
    
  EndProcedure
  
  Procedure Reset()
    
    Instance\IsInitialize = 0
    Instance\Salt = 0
    
  EndProcedure
  
  Procedure.s Encode(P_String.s)
    
    If Instance\IsInitialize = #True
      For i = 1 To Len(P_String)
        encoded.s + Right("0000" + Hex(Asc(Mid(P_String,i,1)) ! ((Instance\Salt + i) % 65535), #PB_Unicode), 4)
      Next
    EndIf
    
    ProcedureReturn UCase(encoded)
  EndProcedure
  
  Procedure.s Decode(P_String.s)
    
    If Instance\IsInitialize = #True
      For i = 1 To (Len(P_String)/4)
        ptr = ((i - 1) * 4) + 1
        decoded.s + Chr(Val("$"+Mid(P_String, ptr, 4)) ! ((Instance\Salt + i) % 65535))                     
      Next
    EndIf
    
    ProcedureReturn decoded
  EndProcedure
  
EndModule

CompilerIf #PB_Compiler_IsMainFile
  
  RollingEncryption::Initialize(65342)
  
  input$ = "It might be useful..."
  
  Encoded$ = RollingEncryption::Encode(input$)
  Decoded$ = RollingEncryption::Decode(Encoded$)
  
  Debug "SOURCE: " + input$
  Debug "CIPHER: " + Encoded$
  Debug "OUTPUT: " + Decoded$
  
  RollingEncryption::Reset()
  
CompilerEndIf

; <<<<<<<<<<<<<<<<<<<<<<<
; <<<<< END OF FILE <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<
The Stone Age did not end due to a shortage of stones !
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 »

Looking how idles code works !
Try to understand how it works, it is clever and very simple !
Looking ever to the smartest codes, think simple !
Now looking how Unicode works, Wikipedia help you, looking for UTF16 !
Looking what is string termination, compare Unicode and Ascii string termination
You understand this, looking also for UTF8 and how this works
But, i self say, this here is absolutely bunkum !
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 »

@Walbus, yes it is simple but my intent was to show a different way to process strings that will work for any format
without the need to use string functions, so it will run quicker but the index technique used isn't documented.

I've quickly added a convert to hex similar to Bo's code, it doesn't look that pretty but as an example it may be instructive
to the parts of PB that aren't so clearly documented.

Code: Select all

Structure char 
  a.c[0]
EndStructure   

Procedure.s EncodeToHex(*input.char,len,salt) 
  Protected *output.char,i,j,*t.Ascii,a.a 
  Protected out.s = Space(len << 1)
  *output = @out  
  salt+1
  For i = 0 To len-1                           
    a = *input\a[i] ! ((salt+i) & 255) 
    *t = ?table + ( a >> 4) 
    *output\a[j] = *t\a
    *t = ?table + (a & 15) 
    *output\a[j+1] = *t\a  
    j+2
  Next
  ProcedureReturn out
  
  DataSection 
    table: 
    Data.a 48,49,50,51,52,53,54,55,56,57,65,66,67,68,69,70 
  EndDataSection 
EndProcedure 

Procedure.s DecodeFromHex(*string,len,salt) 
  Protected *input.char,a.a,*output.char,i,j,*t.Ascii   
  Protected out.s = Space(len >> 1)
  *input = *string 
  *output = @out    
  salt+1
  For j = 0 To len-1 Step 2                            
    *t = ?table + *input\a[j] 
    a = *t\a 
    a << 4 
    *t = ?table + *input\a[j+1]
    a | *t\a 
    a ! ((salt+i) & 255) 
    *output\a[i] = a 
    i+1 
  Next   
  ProcedureReturn out 
  
  DataSection 
    table: 
    Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    Data.a 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9
    Data.a 0,0,0,0,0,0,0,10,11,12,13,14,15 
  EndDataSection   
  
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 = 123456                             
output$ = EncodeToHex(@string$, StringByteLength(string$),salt)  
Debug output$                   
output$ = DecodeFromHex(@output$,StringByteLength(output$),salt)
Debug output$ 


Windows 11, Manjaro, Raspberry Pi OS
Image
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 »

@idle
As always, a nice code from you, also fine for learning !

@StarBootics
Converting to HEX or Base64 is the way for making (Unicode compatible) encrypted strings.
However, it is essential to understand how Unicode and string termination works (inside PB).
Primary, it is simple to using AES with PB for this things.

But, i self think, the AES function inside PB is to rudimentary,
inflexible, not good usable and not good described.
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 »

walbus wrote:@idle
As always, a nice code from you, also fine for learning !
It wasn't quite right though, it's hex string was 1 out to Bo's, fixed now so it's the same
Windows 11, Manjaro, Raspberry Pi OS
Image
User avatar
nco2k
Addict
Addict
Posts: 1344
Joined: Mon Sep 15, 2003 5:55 am

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

Post by nco2k »

why not simply use ROT47?

Code: Select all

Procedure ROT47(*String)
  Protected *Character.Character = *String
  While *Character\c
    If *Character\c > 32 And *Character\c < 127
      *Character\c = (*Character\c + 14) % 94 + 33
    EndIf
    *Character + SizeOf(Character)
  Wend
EndProcedure

Text$ = "Hello World!"
Debug Text$

ROT47(@Text$)
Debug Text$

ROT47(@Text$)
Debug Text$
c ya,
nco2k
If OSVersion() = #PB_OS_Windows_ME : End : EndIf
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 »

@nco2k
This is unfair, it´s to simple LOL
(But, it´s not for Unicode, only for ascii characters and a standard method, known as caesar encryption)
User avatar
nco2k
Addict
Addict
Posts: 1344
Joined: Mon Sep 15, 2003 5:55 am

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

Post by nco2k »

well, the task was to make strings unreadable with hex editors and ROTn is probably the best and simplest way to do it. if you want to make it secure however, you should use AES. but as long as you store the key in the same exe, its pretty easy to crack though.

as of unicode, im pretty sure similar algorithms exist. unfortunately i dont know any, since i never needed such a thing. :)

c ya,
nco2k
If OSVersion() = #PB_OS_Windows_ME : End : EndIf
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 »

Crypter code removed

Now included in QAES...
Last edited by walbus on Sat Apr 16, 2016 12:43 am, edited 20 times in total.
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 »

SHA3 and AES? somebody missed the "trivial encoding" part of the brief :D and they are small but i believe part of the intention is to keep the codec tiny!?
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 »

I think it is a helpfull code :wink:
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 »

Not a huge fan of Rot xx - it's basically baby's first cipher... and I hate to say it, but reversing the string is pretending that a person who opens your program in a hex editor won't be smart enough to read english text when it's written right to left instead of left to right.

But that's just my take on it... :)

These are all valid approaches, but i like stream ciphers. A stream cipher was good enough to fool the allies until the Polish secret service and some salesmen in Spain basically handed over the source code, and even then it took a brilliant mind (with a taste for the unusual) to build a machine to crack it. And even then, they only managed THAT because the germans liked political salutations and said the same things over and over... and Turing used it as a validation tool to eliminate wasted effort.

Ironically, for a while, cryptolocker virus writers stopped locking .exe files for this same reason - it was computationally easy to reverse engineer the encoding scheme because .exes were well known, and you could qualify a key by looking to see if the first few bytes bore the signature of an .exe. That meant you only had to decode a single block and see if the signature appeared - a huge speed increase when brute forcing.

This wasn't meant to be real crypto, but it's a cheap and cheerful stream cipher that only nerdy crypto cats know about, and most casual crackers aren't really crypto cats - they load up a debugger and poke around, and as everyone knows - at that point (unless you know a little more) it's game over anyway. Add 7 more terms to the XOR sequence and a permutation or two, and you'll be achieving state of the art crypto... for 1939, anyway. But if it was good enough for grandpa... :)

I'm glad I posted it, because it turns out that this is one of those topics that comes up again and again and again... and with it, i discovered other people who followed the official philosophy of the dedicated PureBasic programmer: Reinventing the wheel is half the fun! :)

Thank you to everyone. I hope it's useful.
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 »

delta encoding is just as simple as 8bit-xor or rot13, but because it transforms into deltas (the difference between two bytes, eg "b"<>"e" delta=3) the byte values are lost until transformed back, which means you can't simply do the "xor/add all 255 possible combinations" brute force to recover it, you just recover rubbish :) (for example "123" becomes "111", so you can try all 255 combinations and get 222, 333, etc, but not the original 123)

Code: Select all

Plaintext: 54 68 65 20 73 65 63 72 65 74 20 69 73 20 31 32 33   The secret is 123
Encoded:   55 15 FE BC 54 F3 FF 10 F4 10 AD 4A 0B AE 12 02 02   U.þ¼Tóÿ.ô.­J.®..
because a delta can be 0 i simply +1 all encoded results, and we can do that because the maximum delta is 255-1=254 due to nullchar not being used in strings. Supports ascii+unicode

Code: Select all

Procedure delta_encode(*buffer.Character, length)
  Protected last.c, current.c
  For i = 0 To length-1 Step SizeOf(Character)
    current = *buffer\c
    *buffer\c = (current-last)+1
    last = current           
    *buffer+SizeOf(Character)
  Next
EndProcedure

Procedure delta_decode(*buffer.Character, length)
  Protected last.c, delta.c
  For i = 0 To length-1 Step SizeOf(Character)
    delta = *buffer\c
    *buffer\c = (delta+last)-1
    last = *buffer\c
    *buffer+SizeOf(Character)
  Next
EndProcedure

;EXAMPLE
Define sTxt.s, sEnc.s

;For i = 1 To 255: sTxt + Chr(i): Next   ;all non-null chars
sTxt = "The secret is 123"
sEnc.s = sTxt
delta_encode(@sEnc,Len(sEnc))
MessageRequester("OK","Encoded=" + sEnc)

delta_decode(@sEnc,Len(sEnc))
MessageRequester("OK","Decoded=" + sEnc)

If sEnc = sTxt
  MessageRequester("Success", "Decrypt matches")
Else
  MessageRequester("Error", "Decrypt doesn't match")
EndIf
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 »

The idea of delta encoding is very nice Keya.
Your code however doesn't work.

Code: Select all

sTxt = "321 The secret is 123"
sEnc.s = sTxt
delta_encode(@sEnc,Len(sEnc))
MessageRequester("OK","Encoded=" + sEnc)

delta_decode(@sEnc,Len(sEnc))
MessageRequester("OK","Decoded=" + sEnc)

If sEnc = sTxt
  MessageRequester("Success", "Decrypt matches")
Else
  MessageRequester("Error", "Decrypt doesn't match")
EndIf
Windows (x64)
Raspberry Pi OS (Arm64)
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 »

aw, i thought i was already accounting for delta=0, my bad! i try again
Post Reply