I'm doing a project where I need to randomly generate Hash numbers.
The code has to work as follows.
A random function generates a random number, these numbers are concatenated with a String to then generate the Hash of this String, ie each time a number is generated, the Hash of that number is also generated, this must be looped. To generate the hash I'm using a library called SpritzCipher.
The problem with this code is that it generates the hash of the word "random" instead of the hash of the concatenation of the value with String (salt).
Here is the code I did:
#include <SpritzCipher.h>
String salt = "fkllrnjnfd";
int randNumber;
String valorConcat;
void randomico() {
//Serial.begin(9600);
randomSeed(analogRead(0)); // Starts the list of random values
randNumber = random(100); // Draw a number from 0 to 99
valorConcat = String(randNumber) + salt;
//Serial.println(valorConcat); // Sends the value of randNumber to the serial
delay(500); // espera 500 ms
}
/* Data to input */
const byte testData[12] = {randomico};
/* Test vectors */
/* Data = 'testData' hash test vectors */
const byte testVector[32] =
{ 0xff, 0x8c, 0xf2, 0x68, 0x09, 0x4c, 0x87, 0xb9,
0x5f, 0x74, 0xce, 0x6f, 0xee, 0x9d, 0x30, 0x03,
0xa5, 0xf9, 0xfe, 0x69, 0x44, 0x65, 0x3c, 0xd5,
0x0e, 0x66, 0xbf, 0x18, 0x9c, 0x63, 0xf6, 0x99
};
void testFunc(const byte ExpectedOutput[32], const byte *data, byte dataLen)
{
byte hashLen = 32; /* 256-bit */
byte digest[hashLen]; /* Output buffer */
byte digest_2[hashLen]; /* Output buffer for chunk by chunk API */
spritz_ctx hash_ctx; /* the CTX for chunk by chunk API */
unsigned int i;
/* Print input */
for (i = 0; i < dataLen; i++) {
Serial.write(data[i]);
}
Serial.println();
spritz_hash_setup(&hash_ctx);
/* For easy test: code add a byte each time */
for (i = 0; i < dataLen; i++) {
spritz_hash_update(&hash_ctx, data + i, 1);
}
spritz_hash_final(&hash_ctx, digest_2, hashLen);
spritz_hash(digest, hashLen, data, dataLen);
for (i = 0; i < sizeof(digest); i++) {
if (digest[i] < 0x10) { /* To print "0F" not "F" */
Serial.write('0');
}
Serial.print(digest[i], HEX);
}
/* Check the output */
if (spritz_compare(digest, ExpectedOutput, sizeof(digest)) || spritz_compare(digest_2, ExpectedOutput, sizeof(digest_2))) {
/* If the output is wrong "Alert" */
digitalWrite(LED_BUILTIN, HIGH); /* Turn pin LED_BUILTIN On (Most boards have this LED connected to digital pin 13) */
Serial.println("\n** WARNING: Output != Test_Vector **");
}
Serial.println();
}
void setup() {
/* Initialize serial and wait for port to open */
Serial.begin(9600);
while (!Serial) {
; /* Wait for serial port to connect. Needed for Leonardo only */
}
/* initialize digital pin LED_BUILTIN (Most boards have this LED connected to digital pin 13) as an output */
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
}
void loop() {
Serial.println("[Spritz spritz_hash*() test]\n");
/* Data: arcfour */
testFunc(testVector, testData, sizeof(testData));
delay(5000); /* Wait 5s */
Serial.println();
}
A lot of your hashing code is just and example of two different options of hashing an array of bytes and comparing it to a known hash.
Since you only need to calculate the hash you only need to call spritz_hash
.
As for your string generation, a more efficient way would be to use low level C++ functions, since the String
object is using dynamic memory allocation and that can cause memory problems.
#include <SpritzCipher.h>
#define hex_char(n) ((n) < 10 ? '0' + (n) : 'A' + ((n)-10))
const char salt[] = "fkllrnjnfd";
char string[13] = "";
byte hash[32]; // byte hash
char hash_string[65]; // hex string hash
void randomico(char *string)
{
int randNumber = random(100); // Draw a number from 0 to 99
itoa(randNumber, string, 10); // convert int into char array
strcat(string, salt); // concatenate salt
}
void bytes_to_hexstr(char *string, byte *bytes, int size)
{
for (int i = 0; i < size; i++)
{
string[i*2] = bytes[i] < 16 ? '0' : hex_char((bytes[i] >> 4) & 0xF);
string[i*2+1] = hex_char(bytes[i] & 0xF);
}
string[size*2] = 0;
}
void setup()
{
Serial.begin(115200);
while (!Serial);
randomSeed(analogRead(0)); // Starts the list of random values
}
void loop()
{
randomico(string); // generate random salted string into 'string' variable
spritz_hash(hash, 32, (byte*)string, strlen(string)); // hash 'string' into 'hash' variable (hash only the character inside the string not the full char array)
bytes_to_hexstr(hash_string, hash, 32); // convert byte hash into printable hex string
// print out string and hash
Serial.print(string);
Serial.print(" -> ");
Serial.println(hash_string);
delay(1000);
}
But if you really want to use String
you can do it as such:
String str = String(random(100))+salt;
spritz_hash(hash, 32, (byte*)str.c_str(), str.length());