I've been working on a cipher based project, and I wanted to prep the encrypted string for use with the RF24 library. Since the payload size for the RF24 module is 32 bytes, I wanted to stick with that size permanently. The key number (against which the encryption keys are stored) has to be embedded at the end of the char array, and I was converting it to a char to embed. To make the message up to 31 bytes if it was smaller than 31 bytes, I am padding with zeroes.
The cipher functions themselves (namely loadInput(), cipherText() and originalText()), work perfectly; I have tested these by themselves numerous times.
However, the other two functions I wrote for padding and de-padding are behaving erratically.
My code:
const String keys[] = {
"TTZUZRZJHP",
"SUENIFKGAT",
"CEXGWKMCVQ",
"SIACAKRFM",
"CSMKSWSNLH",
"IPIJWROJBB",
"SZSGAMYJGJ",
"BIHLBNUIJS",
"UTFGSQAISS",
"SSPXJXURJV",
"XPDRYPOFAC",
"DROIFANPZE",
"DKTZXUQLAM",
"UDHAWMAJTG",
"HKTQMEPWXS",
"IRUQAHZSBP",
"ZHZAAGTMTN",
"EHORTISSLQ",
"NYZZQALWTP",
"PEEGDJLQLQ",
"UNQGHTXFSG",
"NOBSTVFLAX",
"GQJYEVUNCX",
"UTJDNOCLSP",
"XQNGBDOBEN",
"FURHLIZSIN",
"AAAPEIGRHI",
"QWQFCCVFPV",
"KZEFJHUJWB",
"NDJNLHURJO"
};
char readyToSend[32]; //global array, which is to be transmitted via RF24
char recieved[32]; // global array, which is to be recieved via RF24
int keyRecieved; //global key number, which is to be embedded as the last char recieved[]
String loadInput() { //this functions takes the input string and checks it's validity
bool isValid = true;
String(inputStr);
do {
Serial.println("Enter valid input. Only enter ALPHABETIC characters. ONLY 31 CHARS MAX.");
Serial.println("Whitespaces are valid but commas and fullstops are not");
while (Serial.available () == 0) {}
inputStr = Serial.readString();
int inputLength = inputStr.length();
for (int i=0; i<inputLength; i++) {
if (inputLength>31) {
Serial.println("Input longer than 31 chars.");
isValid = false;
break;
} else if (inputStr[i] > 95 && inputStr[i] < 123) {
inputStr[i] -= 32;
} else if (isWhitespace(inputStr[i])) {
} else if (!isAlpha(inputStr[i])) {
isValid = false;
break;
}
}
} while (isValid == true);
inputStr.remove((inputStr.length()-2), 2);
return inputStr;
}
String cipherText(String str,const String key) { //this function encrypts the message, and returns the encrypted version
String cipher_text;
for (int i=0; i<str.length(); i++) {
if (isWhitespace(str[i])) {
cipher_text += ' ';
} else {
char x = (str[i] + key[i%key.length()]) %26;
x += 'A';
cipher_text += x;
}
}
Serial.println(cipher_text);
return cipher_text;
}
String originalText( String cipher_text,const String key) { //this function decrypts the message, and returns the decrypted version
String orig_text;
for (int i=0 ; i<cipher_text.length(); i++) {
if (isWhitespace(cipher_text[i])) {
orig_text += ' ';
} else {
// converting in range 0-25
char x = (cipher_text[i] - key[i%key.length()] + 26) %26;
// convert into alphabets(ASCII)
x += 'A';
orig_text += x;
}
}
return orig_text;
}
void prepForTransmit(String input, int keyNumber) { //this function makes pads the string upto 31 with '0', then embeds key
input.toCharArray(readyToSend, 32);
int zeroesStart = input.length();
for (int i=zeroesStart; i<32; i++) {
readyToSend[i] = '0';
}
char keyNumberAsChar = (char)(keyNumber + 65);
readyToSend[31] = keyNumberAsChar;
return;
}
String PrepForDecode() { //this function makes exctracts key, then removes padding
keyRecieved = (recieved[31] - 65);
String toEdit = String(recieved);
toEdit.remove(31, 1);
if (toEdit.indexOf('0') != -1) {
toEdit.remove(toEdit.indexOf('0'), (31-toEdit.indexOf('0')));
} else {
}
return toEdit;
}
void setup() { // TEST CODE
Serial.begin(9600);
randomSeed(analogRead(A0)); //SEED RANDOM FUNCTION
String(text) = loadInput(); //GET INPUT
Serial.println(text); //PRINT INPUT <--------------------------------------
int keynumber = random(25); // |
String encrypted_message = cipherText( text, keys[keynumber]); //ENCRYPT THIs _|
Serial.println("Using key number ");
Serial.println(keynumber);
prepForTransmit(encrypted_message, keynumber); // PADDING AND ADD KEYNUMBER
Serial.println("Message to trasmit through radio is: ");
Serial.println(readyToSend); // PRINT PREPPED CHAR ARRAY
for (int i=0; i<32; i++) {
recieved[i] = readyToSend[i]; // COPY PREPPED ARRAY TO EMULATE RECEPTION FROM RADIO
}
String toDecode = PrepForDecode(); // PREP RECIEVED STRING FOR DECODING (REMOVE PADDING, EXTRACT KEY)
Serial.println(originalText( toDecode , keys[keyRecieved])); // PRINT DECODED STRING
}
void loop() { //main program
My serial output:
22:18:59.596 -> Whitespaces are valid but commas and fullstops are not
22:19:08.255 -> THIS PROJECT IS A MESS
22:19:08.290 -> LPIU ZITVWKT IC F EMSU
22:19:08.325 -> Using key number
22:19:08.325 -> 3
22:19:08.325 -> Message to trasmit through radio is:
22:19:08.393 -> LPIU ZITVWKT IC F EMSU000000000D⸮!
22:19:08.428 -> THIS PROJECT IS A MESSLFRP HATTWAC WK F ECBP>8BJHJ@9ER:3
"LPIU ZITVWKT IC F EMSU000000000D⸮!" is very unexpected, since there should only be 32 chars, and here there are 34.
Furthermore, the behavior here: "THIS PROJECT IS A MESSLFRP HATTWAC WK F ECBP>8BJHJ@9ER:3" is something I absolutely cannot understand.
I am baffled, and I would really appreciate help. I apologize in advance if the error is something small or stupid, but I cannot understand what's going on here.