Text encryption
#1
Ok, here is a simple program to encode text with a shifting cypher.

Usage:-
  crypt encode 1234 "your data"
  crypt decode 1234 "encoded data"

Code: (Select All)
$CONSOLE:ONLY
CLS
DIM SHARED AS STRING phrase, message, code
REDIM SHARED AS INTEGER sCode(0)
phrase = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
SplitCode
SELECT CASE LCASE$(COMMAND$(1))
    CASE "encode"
        en$ = EnCode
        PRINT "EnCode<", en$
        _CLIPBOARD$ = en$
        PRINT
        PRINT "encoded message has been copied to clipboard"
        SYSTEM
    CASE "decode"
        de$ = DeCode
        PRINT "DeCode>", de$
        _CLIPBOARD$ = de$
        SYSTEM
END SELECT

FUNCTION DeCode$
    DIM AS STRING t, h, e
    DIM AS INTEGER c
    c = 1
    h = UCASE$(COMMAND$(3))
    FOR i = 1 TO LEN(h)
        FOR x = 1 TO LEN(phrase)
            IF MID$(h, i, 1) = MID$(phrase, x, 1) THEN
                e = e + MID$(phrase, x - sCode(c), 1)
                EXIT FOR
            END IF
        NEXT x
        IF c = 4 THEN c = 1 ELSE c = c + 1
    NEXT i
    DeCode = dehex(e)

END FUNCTION

FUNCTION EnCode$
    DIM AS STRING t, h, e
    DIM AS INTEGER c
    c = 1
    h = toHex(COMMAND$(3))
    FOR i = 1 TO LEN(h)
        FOR x = 1 TO LEN(phrase)
            IF MID$(h, i, 1) = MID$(phrase, x, 1) THEN
                e = e + MID$(phrase, x + sCode(c), 1)
                EXIT FOR
            END IF
        NEXT x
        IF c = 4 THEN c = 1 ELSE c = c + 1
    NEXT i
    EnCode = e

END FUNCTION

SUB SplitCode
    REDIM sCode(LEN(COMMAND$(2))) AS INTEGER
    FOR i = i TO LEN(COMMAND$(2))
        sCode(i) = VAL(MID$(COMMAND$(2), i, 1))
    NEXT
END SUB

FUNCTION dehex$ (m AS STRING)
    DIM s AS STRING
    FOR i = 1 TO LEN(m) STEP 2
        s = s + CHR$(VAL("&h" + MID$(m, i, 2)))
        dehex = s
    NEXT

END FUNCTION

FUNCTION toHex$ (m AS STRING)
    DIM s AS STRING
    FOR i = 1 TO LEN(m)
        s = s + HEX$(ASC(MID$(m, i, 1)))
        toHex = s
    NEXT
END FUNCTION


Attached Files
.bas   crypt.bas (Size: 1.84 KB / Downloads: 70)
Reply
#2
Cool.  I've always had a fascination with crypto, although I am certainly no expert.  I know just enough about the subject to NEVER trust my own work.  Actually, after testing the program below to make sure it worked, I filed it away and it's been my shameful little secret for years, so YOU, dear reader, are among the only people in the world, besides me, who know about this program.

This was written, as a proof-of-concept, for GWBasic back in the bronze age.

It uses a combination of substitution (by adding a "random" number to each byte), and transposition (rearrangement of bytes).

Due to the repeatable nature of the linear congruential random number generator used by GWB (and QB and QB64PE), the sequence of "random" numbers used for encryption may be easily recreated for decryption.

The program asks for the name of an Input File (which is the file you want to encrypt or decrypt), an Output File (which will contain the encrypted or decrypted data), and a Key (which will be used as the "seed" for Basic's built-in pseudo-random number generator).

Exclamation WARNING: Exclamation Be careful with your filename typing; this program does not ask for confirmation if a file with your Output name already exists!

Code: (Select All)
5 'File Security Series, Part 1.
6 'Due to the nature of GWBASIC's random number generator,
7 'this program must be rerun *EVERY* time it is used.
10 DefInt A-Z: Dim A1(255), A2(255), A3(1, 127)
50 Cls: Print "Pseudo-random file cypher utility.": Print "Written by Jim Race.": Print: Print
51 Input "(E)ncypher, (D)ecypher, or (Q)uit"; I$: I = Int(InStr("EeDdQq", I$) / 2 + .5): If I = 0 Then 51
52 Print
53 If I = 3 Then End

60 FI$ = "": Line Input "Input filename : "; FI$
70 FO$ = "": Line Input "Output filename: "; FO$
80 Print: Input "Key (numeric): ", K

100 Cls: Print "wait...";: Randomize (K)

130 Open "R", 1, FI$, 1: Field 1, 1 As Z1$
140 Open "R", 2, FO$, 1: Field 2, 1 As Z2$

150 On I GOSUB 200, 500
160 Close: Print "done!": Run

199 'Encypher....
200 GoSub 1000: If L = -1 Then Return
210 For A = 0 To I: A1(A) = (A1(A) + Int(Rnd * 9472)) And 255: Next '  Addition of pseudo-random number
220 J = Int(I / 2): For A = 0 To J '  Transposition
230 R = Int(Rnd * (I + 1)): S = Int(Rnd * (I + 1)): Swap A1(R), A1(S): Next
240 GoSub 2000: GoTo 200

499 'Decypher....
500 GoSub 1000: If L = -1 Then Return
510 For A = 0 To I: A2(A) = Int(Rnd * 9472): Next
520 J = Int(I / 2): For A = 0 To J
530 A3(0, A) = Int(Rnd * (I + 1)): A3(1, A) = Int(Rnd * (I + 1)): Next
540 For A = J To 0 Step -1: Swap A1(A3(0, A)), A1(A3(1, A)): Next '  Transposition
550 For A = 0 To I: A1(A) = (A1(A) - A2(A)) And 255: Next '  Subtraction of pseudo-random number
560 GoSub 2000: GoTo 500

999 'Read a random number of bytes from the input file....
1000 L = Int(Rnd * 256): I = 0
1010 If Loc(1) = LOF(1) Then Close: L = -1: Return
1020 Get 1: A1(I) = Asc(Z1$)
1030 If L > 0 And (Loc(1) < LOF(1)) Then I = I + 1: L = L - 1: GoTo 1020
1040 Return

1999 'Write A1(0)...A1(I) to the output file....
2000 For A = 0 To I
2010 LSet Z2$ = Chr$(A1(A)): Put 2: Next
2020 Return


The code above is unchanged except for the added blank lines to break things into functional blocks.  I've always written somewhat "dense" code, ESPECIALLY in olden times.

This is what I've always called a "kid brother" cipher, due to it's reliance on a linear congruential generator.
LCGs are fast, but simple, and NOT cryptographically secure.
This might protect your teenage poetry and sappy love letters from your snot-nosed little sibling, but it WILL NOT stop a knowledgeable code breaker.

Lightly tested under QB64PE.  Compiles & seems to run fine.  Just posting it here in case anyone wants to tinker with it.
(My few simple tests seem to indicate that you can ignore the comments in lines 6 & 7 if compiling with QB64PE.)


(For any would-be employers reading this, my coding style and level of sophistication have greatly improved in the years since this program was written.)
Reply
#3
(11-17-2022, 07:59 PM)JRace Wrote: Cool.  I've always had a fascination with crypto, although I am certainly no expert.  I know just enough about the subject to NEVER trust my own work.  Actually, after testing the program below to make sure it worked, I filed it away and it's been my shameful little secret for years, so YOU, dear reader, are among the only people in the world, besides me, who know about this program.

This was written, as a proof-of-concept, for GWBasic back in the bronze age.

It uses a combination of substitution (by adding a "random" number to each byte), and transposition (rearrangement of bytes).

Due to the repeatable nature of the linear consequential random number generator used by GWB (and QB and QB64PE), the sequence of "random" numbers used for encryption may be easily recreated for decryption.

The program asks for the name of an Input File (which is the file you want to encrypt or decrypt), an Output File (which will contain the encrypted or decrypted data), and a Key (which will be used as the "seed" for Basic's built-in pseudo-random number generator).

Exclamation WARNING: Exclamation Be careful with your filename typing; this program does not ask for confirmation if a file with your Output name already exists!
Thank you for this program. I made the modification for output file existence, refusing to do anything in that case. But it's what I chose to do.

Must be tested: run this program a few times to ensure the decrypt/encrypt goes down as expected on the same data set. Then run a program which employs "RANDOMIZE TIMER", run it (hopefully it would be a short time). After that, load this program again and test the decrypt/encrypt like before. It might be easy to emulate eg. the Timex Sinclair random number generator (I read somewhere it just stores 64KB jumbled-up numbers and always refers to that table) but trying to do it for a 16-bit software interpreter and ancient Intel-based processors is harder.

That said, an antidote is to place "RANDOMIZE" statement alone as one of the first lines in the code, then involve the integer that must be input to start, into the encryption.
Reply
#4
This reminds me I need to update my own encryption code for spaces and punctuation...
b = b + ...
Reply
#5
Quote:@mnrvovrfc : I made the modification for output file existence, refusing to do anything in that case. But it's what I chose to do.

That's the way I usually do it in programs I write for myself: if the program finds an error, it reports the error then aborts.



Quote:@bplus : This reminds me I need to update my own encryption code for spaces and punctuation...

Spaces?  Those were optional in TRS-80 Basic and I usually opted out, to conserve memory & diskette space.  Also, interpreted Basic programs were a couple percentage points faster without extra spaces.

I found the requirement for spaces to be quite annoying when I first took up GWBasic.
Reply
#6
@JRace, 

I think you misunderstand, I mean encrypt spaces and punctuation along with letters and digits, so word lengths or formats don't give away the contents of the message.
b = b + ...
Reply
#7
If I can figure out the API for Windows cryptography, I will post something here for that.
Ask me about Windows API and maybe some Linux stuff
Reply
#8
@bplus :

Quote:I think you misunderstand, I mean encrypt spaces and punctuation along with letters and digits, so word lengths or formats don't give away the contents of the message.


Aha.

Yeah, you don't want to give the Bad Guys any freebies for their decryption efforts.
Reply
#9
I am like JRace, I don't know anything about encryption but I translated some public domain C code for blowfish encryption, posted it at the extinct forum https://qb64forum.alephc.xyz/index.php?topic=4270.0
Reply




Users browsing this thread: 2 Guest(s)