It's not password protecting but what about using BSAVE/BLOAD to save and load the data files? That way it's stored in binary so you can't just open it up in a text editor to see the contents and it's also faster than regular reading/writing to text files using the old "OPEN filename for INPUT AS #1..." as you can load the whole file into an array when you BLOAD.
I guess you could add another layer of obfuscation by doing a ROT13 type idea like Burger's first suggestion on top of BSAVE/BLOAD.
Another idea is still use BSAVE/BLOAD but instead of hard coding the ROT number, base the ROT encrypt/decrypt on the password provided by the user. That way you don't actually store any password, but it's still the key to unscramble the data in the data file.
Here's a quick example I threw together that works.. though with any home grown encryption, it's not really secure.
Code: Select all
DECLARE SUB loadEncDataFile (fileName AS STRING)
DECLARE SUB saveEncDataFile (fileName AS STRING)
DECLARE SUB rotData (dataStr AS STRING, cipherKey AS INTEGER)
DECLARE FUNCTION getKey% (password AS STRING)
DECLARE FUNCTION unrotData$ (cipherKey AS INTEGER)
CLS
DIM SHARED encData(1 TO 512) AS INTEGER
dataStr$ = "This is a data string and it is currently not scrambled."
PRINT "DATA: "; dataStr$
INPUT "Enter a password: ", password$
cipherKey% = getKey%(password$)
CALL rotData(dataStr$, cipherKey%)
CALL saveEncDataFile("data.dat")
PRINT "Clearing memory..."
CLEAR
CALL loadEncDataFile("data.dat")
INPUT "Enter password to decode: ", password$
cipherKey% = getKey%(password$)
finalData$ = unrotData$(cipherKey%)
PRINT "Decoded: "; finalData$
END
FUNCTION getKey% (password AS STRING)
cipherKey% = 0
FOR i% = 1 TO LEN(password)
char$ = MID$(password, i%, 1)
cipherKey% = cipherKey% + ASC(char$) * i%
NEXT i%
PRINT "Cipher key: "; cipherKey%
getKey% = cipherKey%
END FUNCTION
SUB loadEncDataFile (fileName AS STRING)
DEF SEG = VARSEG(encData(1))
BLOAD fileName, VARPTR(encData(1))
DEF SEG
PRINT "Loaded file: "; fileName
END SUB
SUB rotData (dataStr AS STRING, cipherKey AS INTEGER)
FOR i% = 1 TO LEN(dataStr)
IF i% < UBOUND(encData) THEN
rotChar% = ASC(MID$(dataStr, i%, 1)) + cipherKey
encData(i%) = rotChar%
END IF
NEXT i%
END SUB
SUB saveEncDataFile (fileName AS STRING)
bytes% = LEN(encData(1)) * UBOUND(encData) + 1
DEF SEG = VARSEG(encData(1))
BSAVE fileName, VARPTR(encData(1)), bytes%
DEF SEG
PRINT "Saved file: "; fileName
END SUB
FUNCTION unrotData$ (cipherKey AS INTEGER)
outData$ = ""
FOR i% = 1 TO UBOUND(encData)
charVal% = encData(i%) - cipherKey
IF charVal% > 0 AND charVal% < 255 THEN
char$ = CHR$(charVal%)
outData$ = outData$ + char$
END IF
NEXT i%
unrotData$ = outData$
END FUNCTION
The program takes the data string and adds the password key to each character. Then saves it using bsave and clears the memory. After that, it loads the data back into memory using bload and attempts to undo the scramble using the 2nd prompted for password.
On success, it displays the unscrambled string. On failures, it will either display nothing if the calculated integer value is too large or small to be represented as ASCII or potentially garbage characters based on a wrong calculated offset.
Example successful output:
Code: Select all
DATA: This is a data string and it is currently not scrambled.
Enter a password: password
Cipher key: 3970
Saved file: data.dat
Clearing memory...
Loaded file: data.dat
Enter password to decode: password
Cipher key: 3970
Decoded: This is a data string and it is currently not scrambled.
Example of wrong decrypt password:
Code: Select all
DATA: This is a data string and it is currently not scrambled.
Enter a password: password
Cipher key: 3970
Saved file: data.dat
Clearing memory...
Loaded file: data.dat
Enter password to decode: wrong
Cipher key: 1635
Decoded:
What it looks like if you try to view contents of data.dat outsite of bload/bsave: