I'm trying to copy a password scrambler from Javascript
to C
. What it does is take the ASCII character code of the letter, floor it, divide it, and grab a random character out of a given list.
Javascript version:
function getScrambledPassword(pwd) {
var cipher = ['k', 's', 'z', 'h', 'x', 'b', 'p', 'j', 'v', 'c', 'g', 'f', 'q', 'n', 't', 'm'];
var result="";
if (pwd == null)
pwd = "";
pwd = encodeURIComponent(pwd);
//alert("encoded password: " + pwd);
for(var i=0;i<pwd.length;i++) {
var cc = pwd.charCodeAt(i);
result += cipher[Math.floor(cc/16)] + cipher[cc%16];
}
//alert("scrambled password: " + result);
return result;
}
Example of the scrambler being run: https://jsfiddle.net/w5db66va/
What I've done so far:
#include <stdio.h>
#include <math.h>
#include <string.h>
static char *scramblePassword(char *pwd)
{
char *cipher[] = {
"k", "s", "z", "h",
"x", "b", "p", "j",
"v", "c", "g", "f",
"q", "n", "t", "m"
};
char *result = "";
for(int i=0; i < strlen(pwd); i++)
{
int cc = (int) pwd[i];
printf("%d", cc);
result + cipher[floor(cc/16)] + cipher[cc%16];
}
return *result;
}
int main(void)
{
char *test[] = {"test", "testtwo", "testthree"};
for (int i=0;i < sizeof(test); i++)
{
printf("Original: %s", test[i]);
printf("Scrambled: %s", scramblePassword(test[i]));
}
}
The issue I'm experiencing is that when I run the c
file (after compilation) it will not output anything at all. What am I doing wrong to the point that I cannot get this to run as I'd expect it?
Continuing from the comment, your problems run a bit deeper than you may first think. To begin, you do not want cipher
to be an array of strings, you simply want it to be a character array, e.g.:
char cipher[] = "kszhxbpjvcgfqnm";
Next, you cannot return an array that is declared within the body of a function. The memory for result
is destroyed when scramblePassword
returns. Your choices are (1) dynamically allocate result
in scramblePassword
(and free it in main
), or (2) declare storage for result
in main
and pass it as a parameter to scramblePassword
. e.g.:
#define MAX 32
static char *scramblePassword (char *pwd, char *result)
{
...
return result;
}
int main(void)
{
char result[MAX] = "";
...
printf ("Scrambled: %s\n", scramblePassword (test[i], result));
Finally, your algorithm, if intended to build an array of scrambled characters from cipher
will result in choosing indexes beyond the bounds of cipher
resulting in undefined behavior. If the intent is to just assign a value to result[x]
regardless of whether it is a valid printable ASCII value, then it may be OK. But if the first is your goal, the results of the algorithm must always result in a value that is within the bounds of cipher
, e.g. something like:
result[i] = cipher[((int)floor (cc / 16) + cc % 16) % sizeof cipher];
Putting all those pieces together, and recalling that main
is type int
and therefore returns a value, you could do something like:
#include <stdio.h>
#include <math.h>
#include <string.h>
#define MAX 32
static char *scramblePassword (char *pwd, char *result)
{
char cipher[] = "kszhxbpjvcgfqnm";
int i;
for (i = 0; i < (int)strlen (pwd); i++)
{
int cc = (int) pwd[i];
// result[i] = cipher[(int)floor (cc / 16)] + cipher[cc % 16];
result[i] = cipher[((int)floor (cc / 16) + cc % 16) % sizeof cipher];
}
result[i] = 0; /* you MUST nul-terminate to use as a string */
return result;
}
int main(void)
{
char *test[] = {"test", "testtwo", "testthree"};
char result[MAX] = "";
for (int i = 0; i < (int)(sizeof test/sizeof *test); i++)
{
printf ("\nOriginal : %s\n", test[i]);
printf ("Scrambled: %s\n", scramblePassword (test[i], result));
}
return 0;
}
Example Use/Output
Which would then result in readable output of:
$ ./bin/pwscramble
Original : test
Scrambled: ffgf
Original : testtwo
Scrambled: ffgffmb
Original : testthree
Scrambled: ffgffmcff
I'll leave it to you to research what that algorithm is actually supposed to do. Let me know if you have further questions.