' XOR Cipher — encrypts/decrypts data using XOR with key
#COMPILE EXE
#DIM ALL

FUNCTION PBMAIN() AS LONG
    LOCAL plaintext AS STRING
    LOCAL keyVal AS LONG
    LOCAL keyStr AS STRING
    LOCAL ciphertext AS STRING
    LOCAL decrypted AS STRING
    LOCAL i AS LONG
    LOCAL j AS LONG
    LOCAL p AS LONG
    LOCAL k AS LONG
    LOCAL c AS LONG
    LOCAL d AS LONG
    LOCAL keyIdx AS LONG
    LOCAL keyLen AS LONG
    LOCAL textLen AS LONG
    LOCAL testCount AS LONG
    LOCAL passCount AS LONG
    LOCAL failCount AS LONG
    LOCAL hexCipher AS STRING
    LOCAL hexDecrypt AS STRING
    LOCAL nibbleVal AS LONG
    LOCAL ch AS STRING
    LOCAL byteVal AS LONG
    testCount = 0
    passCount = 0
    failCount = 0
    PRINT "============================================"
    PRINT "           XOR CIPHER"
    PRINT "============================================"
    PRINT ""
    PRINT "Single-byte XOR encryption:"
    PRINT ""
    plaintext = "Hello World! This is a test."
    keyVal = 85
    PRINT "Plaintext:  " + plaintext
    PRINT "Key byte:   " + STR$(keyVal)
    PRINT ""
    textLen = LEN(plaintext)
    ciphertext = ""
    hexCipher = ""
    FOR i = 1 TO textLen
        ch = MID$(plaintext, i, 1)
        p = ASC(ch)
        c = p XOR keyVal
        ciphertext = ciphertext + CHR$(c)
        hexCipher = hexCipher + " " + HEX$(c)
    NEXT i
    PRINT "Ciphertext hex:" + hexCipher
    PRINT ""
    decrypted = ""
    FOR i = 1 TO textLen
        ch = MID$(ciphertext, i, 1)
        c = ASC(ch)
        d = c XOR keyVal
        decrypted = decrypted + CHR$(d)
    NEXT i
    PRINT "Decrypted:  " + decrypted
    testCount = testCount + 1
    IF decrypted = plaintext THEN
        passCount = passCount + 1
        PRINT "PASS"
    ELSE
        failCount = failCount + 1
        PRINT "FAIL"
    END IF
    PRINT ""
    PRINT "============================================"
    PRINT "     MULTI-BYTE XOR (repeating key)"
    PRINT "============================================"
    PRINT ""
    plaintext = "The quick brown fox jumps over the lazy dog"
    keyStr = "XORKEY"
    keyLen = LEN(keyStr)
    textLen = LEN(plaintext)
    PRINT "Plaintext: " + plaintext
    PRINT "Key:       " + keyStr
    PRINT ""
    ciphertext = ""
    FOR i = 1 TO textLen
        ch = MID$(plaintext, i, 1)
        p = ASC(ch)
        keyIdx = ((i - 1) MOD keyLen) + 1
        k = ASC(MID$(keyStr, keyIdx, 1))
        c = p XOR k
        ciphertext = ciphertext + CHR$(c)
    NEXT i
    hexCipher = ""
    FOR i = 1 TO LEN(ciphertext)
        ch = MID$(ciphertext, i, 1)
        c = ASC(ch)
        hexCipher = hexCipher + " " + HEX$(c)
    NEXT i
    PRINT "Ciphertext hex:" + hexCipher
    PRINT ""
    decrypted = ""
    FOR i = 1 TO textLen
        ch = MID$(ciphertext, i, 1)
        c = ASC(ch)
        keyIdx = ((i - 1) MOD keyLen) + 1
        k = ASC(MID$(keyStr, keyIdx, 1))
        d = c XOR k
        decrypted = decrypted + CHR$(d)
    NEXT i
    PRINT "Decrypted: " + decrypted
    testCount = testCount + 1
    IF decrypted = plaintext THEN
        passCount = passCount + 1
    ELSE
        failCount = failCount + 1
    END IF
    PRINT ""
    PRINT "============================================"
    PRINT "     FILE-LIKE BYTE ARRAY XOR"
    PRINT "============================================"
    PRINT ""
    LOCAL dataArr(100) AS LONG
    LOCAL encryptedArr(100) AS LONG
    LOCAL decryptedArr(100) AS LONG
    local arrSize AS LONG
    arrSize = 32
    FOR i = 0 TO arrSize - 1
        dataArr(i) = (i * 17 + 13) MOD 256
    NEXT i
    keyVal = 127
    PRINT "Original byte array (first 10):"
    hexCipher = ""
    FOR i = 0 TO 9
        hexCipher = hexCipher + " " + HEX$(dataArr(i))
    NEXT i
    PRINT hexCipher
    PRINT ""
    FOR i = 0 TO arrSize - 1
        encryptedArr(i) = dataArr(i) XOR keyVal
    NEXT i
    PRINT "Encrypted (first 10):"
    hexCipher = ""
    FOR i = 0 TO 9
        hexCipher = hexCipher + " " + HEX$(encryptedArr(i))
    NEXT i
    PRINT hexCipher
    PRINT ""
    FOR i = 0 TO arrSize - 1
        decryptedArr(i) = encryptedArr(i) XOR keyVal
    NEXT i
    testCount = testCount + 1
    passCount = passCount + 0
    FOR i = 0 TO arrSize - 1
        IF decryptedArr(i) <> dataArr(i) THEN
            failCount = failCount + 1
        END IF
    NEXT i
    IF failCount = 0 THEN
        passCount = passCount + 1
        PRINT "PASS: All bytes decrypted correctly"
    END IF
    PRINT ""
    PRINT "============================================"
    PRINT "     XOR WITH MULTIPLE KEYS"
    PRINT "============================================"
    PRINT ""
    LOCAL keyOptions(6) AS LONG
    keyOptions(0) = 0
    keyOptions(1) = 1
    keyOptions(2) = 128
    keyOptions(3) = 255
    keyOptions(4) = 64
    keyOptions(5) = 170
    keyOptions(6) = 85
    FOR j = 0 TO 6
        keyVal = keyOptions(j)
        plaintext = "TESTDATA"
        textLen = LEN(plaintext)
        ciphertext = ""
        FOR i = 1 TO textLen
            ch = MID$(plaintext, i, 1)
            p = ASC(ch)
            c = p XOR keyVal
            ciphertext = ciphertext + CHR$(c)
        NEXT i
        decrypted = ""
        FOR i = 1 TO textLen
            ch = MID$(ciphertext, i, 1)
            c = ASC(ch)
            d = c XOR keyVal
            decrypted = decrypted + CHR$(d)
        NEXT i
        hexCipher = ""
        FOR i = 1 TO LEN(ciphertext)
            c = ASC(MID$(ciphertext, i, 1))
            hexCipher = hexCipher + " " + HEX$(c)
        NEXT i
        PRINT "Key " + STR$(keyVal) + ": " + hexCipher
        testCount = testCount + 1
        IF decrypted = plaintext THEN
            passCount = passCount + 1
        ELSE
            failCount = failCount + 1
        END IF
    NEXT j
    PRINT ""
    PRINT "============================================"
    PRINT "     XOR PROPERTIES"
    PRINT "============================================"
    PRINT ""
    LOCAL a AS LONG
    LOCAL b AS LONG
    PRINT "XOR properties (a XOR b) XOR b = a:"
    PRINT ""
    FOR a = 0 TO 9
        FOR b = 0 TO 9
            c = a XOR b
            d = c XOR b
            IF d <> a THEN
                PRINT "  FAIL: (" + STR$(a) + " XOR " + STR$(b) + ") XOR " + STR$(b) + " = " + STR$(d)
            END IF
        NEXT b
    NEXT a
    PRINT "  XOR involution property verified"
    PRINT ""
    PRINT "Results: " + STR$(passCount) + " passed, " + STR$(failCount) + " failed"
    FUNCTION = 0
END FUNCTION
