Random String

A

Andrea

Hi,
Anyone could me suggest how to create a function that generates a
random string?

The function should be:
int _RandomString(char** str,int len);
so, it takes an empty string str and it puts in in a random string of
lenght len, and it returns 1 for success 0 otherwise.

Thanks in advance,
best regards,
Andrea
 
M

Malcolm McLean

Andrea said:
Hi,
Anyone could me suggest how to create a function that generates a
random string?

The function should be:
int _RandomString(char** str,int len);
so, it takes an empty string str and it puts in in a random string of
lenght len, and it returns 1 for success 0 otherwise.

Thanks in advance,
best regards,
Andrea
Hope this isn't homework

(untested)

int randomstring(char **str, int len)
{
char *answer = malloc(len + 1);
int i;

if(answer)
{
for(i=0;i<len;i++)
answer = randchar();
answer[len] = 0;
}
*str = answer;

return answer ? 1 : 0;
}

/*
This one is up to you. What do you mean by a random character?
*/
char randchar()
{
char answer;

do
{
answer = rand() % 255;
}
while(! isalnum(ch));

return answer;
}
 
T

Tor Rustad

Andrea said:
Hi,
Anyone could me suggest how to create a function that generates a
random string?

The C library has no RNG, only a PRNG is provided, which may not be
usable for even a Monte-Carlo simulations, far less for any security
programs.

What shall this "random" string be used for?

Getting random numbers from a computer, is a quite hard problem, and
cannot be done unless you have an entropy source of some kind. Your OS
might provide such a source for randomness, for example some Intel CPU's
comes with a build-in RNG.

The function should be:
int _RandomString(char** str,int len);
so, it takes an empty string str and it puts in in a random string of
lenght len, and it returns 1 for success 0 otherwise.

Underscore prefix is polluting the implementation name space.
 
R

Richard Heathfield

Andrea said:
Hi,
Anyone could me suggest how to create a function that generates a
random string?

The function should be:
int _RandomString(char** str,int len);

You can't have the leading underscore, since _RandomString is reserved
for use by the implementation. But you can have RandomString if you
like.
so, it takes an empty string str and it puts in in a random string of
lenght len, and it returns 1 for success 0 otherwise.

Here's one way you could do it:

#include <stdlib.h>
#include <time.h>
#include <stdio.h>

int RandomString(char **str, int len)
{
int rc = 0; /* 1 indicates success */
size_t len_ = len;
if(str != NULL)
{
*str = malloc(len_ + 1);
if(*str != NULL)
{
const char sym[] =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"\"%^&*()_-abcdefghijklmnopqrstuvwxyz"
"+=[]{}\\|,<.>/?"; /* did I miss any? */
size_t maxsym = sizeof sym / sizeof sym[0] - 1;
size_t i = 0;
while(i < len_)
{
int r = maxsym * (rand() / (RAND_MAX + 1.0));
(*str)[i++] = sym[r];
}
(*str) = '\0';
rc = 1;
}
}
return rc;
}

int main(void)
{
int rc = 0;
int maxtrials = 20;
char *s = NULL;
srand((unsigned)time(0));
while(rc == 0 && maxtrials-- > 0)
{
if(RandomString(&s, 42))
{
printf("%s\n", s);
free(s);
}
}
return 0;
}

Sample output:

Gr^hlgopi>jcXhgr>Qv<+0F/<L*tJ0WZsz3Y%rA5pu
i8WJ+TbhPXh*Wdr=R>[oXga"0/DA4]{m>M\xh^"\=3
XJgA6,8<j(bE\cD6mH<d{|+wr^KDV8GuRx{Yr?TV*{
bX%o&A\ZowSae6?zJV|"BLK2k>1?T({{{SfT&_uDP9
o{FnqZ4k+G}7Ib4JbYq%Ogv{.KXqYo+8e1wP%=.O3=
VLYZ(.yIX9zF0vZX_z8T|mVp/xd,7gw^[G]TCodbyX
qyFCIn>Q3{?Zg/IE|Qvpuj\j?4TcgD.R>B&Fy")[R(
N,&)8Wx]8d-0I-4c6kp3/nE%[?]U=G=BAQiJo%9w1j
wJD=wK)_N*G%|5%x"P?N"Af5UO)&6_8]sMqb)J4upL
IiQk"r."1Xcg^\{.W>*(+IscuKvy1(6JAW{cA+/CKb
sn^jk+gAR^T519Qx,RP0c"X%/-O>l-_ZI>4[xl?A9S
GB^),WzJXWkwyjR9g/jAY=7^q{9q1J4IU)pP{baN|F
5szW["V)cuUjJ7aTxbd=t,U*JK2t_<<eou>cHT4tAY
YU),oP(MCLG_r"stFMoA=X{z.8E0=PZLk\GTImhV|x
]kJhYZ{9ar_"c&-q*W2{imxz11)jW"^L7m])8tgi(A
53eeu4.x<f*sZ)u|BDUeY%MO<U3b?am4eLiUQfDLGj
0gCvaN,{[TSBiN)mz(H)bwsFC5uQQ.<Rd788V2?KVR
V0f[mZT{\{nl5+q+C3x8VVG&*c)*w]wD]W2cxV^qMB
WS>9EAC/I_TY/z>*PtU8|J(<wORK0fWX|U)8*k6nE"
7CM4idy/lsICn1"1M%gjz-?Ri&>pDCBLOYQ|>A\i[B

Second sample output:

pxTxN<Y3Jr+ae,/KYVd\o1F<%q)rdI&N1y6Pu(T?IF
axA_4-]h%eji-6T1x\KNGM8Nc[t}=/7WvH}+rv^FU8
x]EC}/5BLMXTa.IO[5N.^4DT{}BT6(%{Vh2Mf8X=Uw
H{tZFh*^d,_rOYjZtp}HfMyiaZr,N7r*/(}D9WhmQA
Zfa40Pu\)VFR0psrk1yW)w[X.>udk6o6mKAna}f2Nv
UN)81C9+-hjX0fUuE1=]7a9IIjAylXf1m8AnKJ-u=E
D=t-i,a*xh0\zJb<3ITjK1rUp>fKs%Y}OEZ|8<X}dY
yYjUUmeoRyq4F%2umuH7m)L7ZU3yLgJ61[%Vb16[+w
\1J<w\p??W)K*|f-s=B/|C+V_XWeLJWEKgA2-+2_Ja
to&TIHHTFB)2)0Z{fm9>=Ue/W8yZg3<UrYp.h|Qw4x
zcyL%Y,bWv\.tO5eplhl2U6sRnli(q%QNLdql)N3OF
04*5iFrK+uf\_|gFb7}?YFK>}\*E.tT.xy2%?tm+-N
t3GUIs^9r=O/zF{PU+5ox]-zQ-f/UAM9D&*VH|(,uv
|g>x\Rk>2^+bOC6{B"0XbD[1a5,20px|RvrJ9WHB+4
nAHt0SG1rsFfuqlpslZcesSQ>%oEeaJNl"2mtJn)/]
8sft^TZ]}0hKRfn1uNc?bIZe}Fxfmw&ua4-?X<]P.(
bN7JP=)=+36Mh/%"dAJ2{u7Zt(UjwQASfId{56s\Az
EsxhEVrYYiE)3|/Ycvqn9Q}nH>t.]]v4helw<XGT1U
=5Oz&+gGaq_%ZpYElO3%Tl20^>YjR"0E)O0>BhDlTl
9tW-|4y>)Dj-E7)erz1r0_21*Djjz/Q,so&mtNjL%N
 
A

Army1987

Andrea said:
Hi,
Anyone could me suggest how to create a function that generates a
random string?

The function should be:
int _RandomString(char** str,int len);
Don't use identifiers which begin with an underscore.
Read www.c-faq.com question 1.29.
so, it takes an empty string str and it puts in in a random string of
lenght len, and it returns 1 for success 0 otherwise.
Is there any reason why you pass a char** rather than a char*?

In portable C, the best thing you can do is a pseudo-random string.
Look up for the function rand(). Come back here if you have
problems.

<OT>
On Unix-lixe systems there is a file called "/dev/random" which
contain random data. You can open it with fopen(), and use eg.
fread(*str, 1, len, randstream); (or fread(str, ...) if you pass
a char* rather than a char**).
</OT>
 
A

Army1987

Malcolm McLean said:
Andrea said:
Hi,
Anyone could me suggest how to create a function that generates a
random string?

The function should be:
int _RandomString(char** str,int len);
so, it takes an empty string str and it puts in in a random string of
lenght len, and it returns 1 for success 0 otherwise.

Thanks in advance,
best regards,
Andrea
Hope this isn't homework

(untested)

int randomstring(char **str, int len)
{
char *answer = malloc(len + 1);
int i;

if(answer)
{
for(i=0;i<len;i++)
answer = randchar();
answer[len] = 0;
}
*str = answer;

return answer ? 1 : 0;
}

/*
This one is up to you. What do you mean by a random character?
*/
char randchar()
{
char answer;

do
{
answer = rand() % 255;
}
while(! isalnum(ch));

return answer;
}


Where did he say that the characters must all be letters and
numbers? (To be more pedantic: Where did he say that his char's are
unsigned? Where did he say that his CHAR_MAX is 255?)
Also, without ever calling srand(), and using the lowest bits of
the result of rand(), the string will be very hardly any random at
all. See FAQ 13.18.
 
R

Richard

Army1987 said:
Don't use identifiers which begin with an underscore.
Read www.c-faq.com question 1.29.

Is there any reason why you pass a char** rather than a char*?

I would guess so that your routine can allocate the memory and store at
the prescribed character pointer location.
In portable C, the best thing you can do is a pseudo-random string.
Look up for the function rand(). Come back here if you have
problems.

<OT>
On Unix-lixe systems there is a file called "/dev/random" which
contain random data. You can open it with fopen(), and use eg.
fread(*str, 1, len, randstream); (or fread(str, ...) if you pass
a char* rather than a char**).
</OT>

--
 
B

Barry Schwarz

Hope this isn't homework

(untested)

int randomstring(char **str, int len)
{
char *answer = malloc(len + 1);
int i;

You probably want to seed rand at this point to avoid always
generating the same string.
if(answer)
{
for(i=0;i<len;i++)
answer = randchar();
answer[len] = 0;
}
*str = answer;

return answer ? 1 : 0;
}

/*
This one is up to you. What do you mean by a random character?
*/
char randchar()
{
char answer;

do
{
answer = rand() % 255;
}
while(! isalnum(ch));

return answer;
}



Remove del for email
 
B

Barry Schwarz

Hi,
Anyone could me suggest how to create a function that generates a
random string?

The function should be:
int _RandomString(char** str,int len);
so, it takes an empty string str and it puts in in a random string of
lenght len, and it returns 1 for success 0 otherwise.

Others have discussed your function name. I address your first
parameter. It is not an empty string. It is a pointer to a pointer
to char and must contain a valid address.

It is possible for the pointed to pointer (*str) to point either to an
uninitialized array of at least len+1 char or to an empty string
which resides at the beginning or such an array. However, none of the
responders to date assumed this. They all assumed that *str pointed
to a pointer they were free to use. This is reasonable given the
prototype but not given the requirement.

So the question is: Did you misinterpret the prototype when you
generated your last statement ("so, it ... otherwise"), did you
generate a prototype inconsistent with the requirement, or did your
instructor provide inconsistent guidance? Which of the following does
the code that calls your function (most instructors do provide a
sample) look like?

1. char *result;
_RandomString(&result, 42); /*your prototype */

2. char result[43] = ""; /* an empty string ... */
_RandomString(result, 42); /* passed to the function */


Remove del for email
 
D

Denis Kasak

"Malcolm McLean" <[email protected]> ha scritto nel messaggio

[snip]
/*
This one is up to you. What do you mean by a random character?
*/
char randchar()
{
char answer;

do
{
answer = rand() % 255;
}
while(! isalnum(ch));

return answer;
}

Where did he say that the characters must all be letters and
numbers? (To be more pedantic: Where did he say that his char's are
unsigned? Where did he say that his CHAR_MAX is 255?)
Also, without ever calling srand(), and using the lowest bits of
the result of rand(), the string will be very hardly any random at
all. See FAQ 13.18.

Which is exactly why Malcolm specified in a comment above the function
that the OP should do it for herself because she didn't specify what she
meant by 'random character'. Your point with the RNG still stands, though.
 
D

Denis Kasak

OT: Andrea can be a male and a female name, esp. in Italy and Switzerland it
frequently is a male name.

I have heard of Andrea being used as a male name, but figured that,
since both are assumptions, I would make the more interesting one :)
If I was wrong, I apologise to the OP.
 
J

Joachim Schmitz

Denis Kasak said:
I have heard of Andrea being used as a male name, but figured that,
since both are assumptions, I would make the more interesting one :)
Fair enough :cool:

Bye, Jojo
 
R

Richard Bos

OT: Andrea can be a male and a female name, esp. in Italy and Switzerland it
frequently is a male name.

In fact, it's a little silly that some languages use it as a female
name. Check an etymological dictionary...

Richard
 
J

Joachim Schmitz

Richard Bos said:
In fact, it's a little silly that some languages use it as a female
name. Check an etymological dictionary...
Maybe disturbing or irritating but not silly.
 
T

Tor Rustad

Richard said:
Andrea said:
Here's one way you could do it:

That was rather a good example of why some application programmers, should
*NOT* implement security software. For the record, I think RH already know,
that we both can write a program which brute-force the seed in "no" time.

I re-wrote your RandomString() function to this function (no malloc and
no '\"' and '\\' symbols):

$ cat rh_random.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <assert.h>
#include <string.h>

/* RH_Random: much FASTER version which DON'T malloc */
void RH_Random(unsigned char *str, size_t len)
{
/* do not include \" and \\ */
const char sym[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"%^&*()_-abcdefghijklmnopqrstuvwxyz"
"+=[]{}|,<.>/?";
size_t maxsym = sizeof sym / sizeof sym[0] - 1;
size_t i = 0;

assert(str);
assert(len > 3);

while (i < len)
{
int r = (int) (maxsym * (rand() / (RAND_MAX + 1.0)));
str[i++] = sym[r];
}
str = '\0';
}

Then I quickly prototyped a program, which checked the randomness by tests
typically used at Power-Up to detect faulty generators:

$ ./fips
Random sequence to test:
<much snipage>

Testing 'monobit_test'...success
Testing 'poker_test'... X = 2151.4 (must be 1.03 X < 57.4) ***FAILED***
Testing 'runs_test'...***FAILED***
Testing 'long_run_test'...success

so unless you can point out a significant error in my code

http://84.202.85.220/C/fips.c

your RandomString() function should be *REJECTED* already at PowerUp!!! :D

I expect, the reason for those failures, was mainly because RH used an
alphabet, which on my system have less randomness in the most-significant
bits.

The bitwise representation of sym[] ="0..." , is implementation defined, so
the above transformation can destroy some of the "randomness" provided by
rand().
 
R

Richard Heathfield

Tor Rustad said:
That was rather a good example of why some application programmers,
should *NOT* implement security software.

I disagree. If I had been *trying* to implement security software, fine,
fair comment - but I wasn't. The OP asked how to generate a random
string. Others had *already pointed out* that the best he or she could
hope for in vanilla C was a *pseudo-random* string. I saw an
implementation elsethread that I considered a little clumsy, so I
figured I'd post something a bit better. I did not and do not claim
that it is cryptographically secure. If you want cryptographically
secure, don't use a PRNG to create passwords!
For the record, I think RH
already know, that we both can write a program which brute-force the
seed in "no" time.

For sufficiently large values of 0, sure.
I re-wrote your RandomString() function to this function (no malloc
and no '\"' and '\\' symbols):

$ cat rh_random.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <assert.h>
#include <string.h>

/* RH_Random: much FASTER version which DON'T malloc */
void RH_Random(unsigned char *str, size_t len)

Doesn't meet the interface spec.
{
/* do not include \" and \\ */
const char sym[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"%^&*()_-abcdefghijklmnopqrstuvwxyz"
"+=[]{}|,<.>/?";
size_t maxsym = sizeof sym / sizeof sym[0] - 1;
size_t i = 0;

assert(str);

Undefined behaviour in C90.
assert(len > 3);

while (i < len)
{
int r = (int) (maxsym * (rand() / (RAND_MAX + 1.0)));

Why the pointless cast?

<snip>
 
T

Tor Rustad

Richard said:
Tor Rustad said:


I disagree. If I had been *trying* to implement security software, fine,
fair comment - but I wasn't. The OP asked how to generate a random
string. Others had *already pointed out* that the best he or she could
hope for in vanilla C was a *pseudo-random* string.


OP asked for *random* string, my test showed that your function failed 2 out
of 4 basic tests for randomness. My main point here, is that I expect your
rand() implementation to pass those tests! Hence, IMO the problem is likely
in *your* transformation to those *symbols*.

We both know that the usage of time() as seed, and stdlib rand() is not
exactly cryptographically secure. BTW, I didn't necessary include *you* in
that group of "some application programmers"! ;)
I saw an
implementation elsethread that I considered a little clumsy, so I
figured I'd post something a bit better. I did not and do not claim
that it is cryptographically secure. If you want cryptographically
secure, don't use a PRNG to create passwords!

If your RandomString() function fail basic statistical tests, it's not a
very good candidate for non-cryptographically usage either, particularly
when the system supplied rand() don't fail those tests.

Doesn't meet the interface spec.

It very much did meet *my* interface spec. :)

Undefined behaviour in C90.

assert(str != NULL);

Why the pointless cast?

To silence a warning, of course.
 
R

Richard Heathfield

Tor Rustad said:
Richard Heathfield wrote:




OP asked for *random* string, my test showed that your function failed
2 out of 4 basic tests for randomness.

The OP asked how to generate a random string. Others had *already
pointed out* that the best he or she could hope for in vanilla C was a
*pseudo-random* string.

But I repeat myself.
 
B

Ben Bacarisse

Tor Rustad said:
Richard said:
Andrea said:
Here's one way you could do it:

That was rather a good example of why some application programmers, should
*NOT* implement security software. For the record, I think RH already know,
that we both can write a program which brute-force the seed in "no" time.

I re-wrote your RandomString() function to this function (no malloc and
no '\"' and '\\' symbols):

$ cat rh_random.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <assert.h>
#include <string.h>

/* RH_Random: much FASTER version which DON'T malloc */
void RH_Random(unsigned char *str, size_t len)
{
/* do not include \" and \\ */
const char sym[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"%^&*()_-abcdefghijklmnopqrstuvwxyz"
"+=[]{}|,<.>/?";
size_t maxsym = sizeof sym / sizeof sym[0] - 1;
size_t i = 0;

assert(str);
assert(len > 3);

while (i < len)
{
int r = (int) (maxsym * (rand() / (RAND_MAX + 1.0)));
str[i++] = sym[r];
}
str = '\0';
}

Then I quickly prototyped a program, which checked the randomness by tests
typically used at Power-Up to detect faulty generators:

$ ./fips
Random sequence to test:
<much snipage>

Testing 'monobit_test'...success
Testing 'poker_test'... X = 2151.4 (must be 1.03 X < 57.4) ***FAILED***
Testing 'runs_test'...***FAILED***
Testing 'long_run_test'...success

so unless you can point out a significant error in my code


Well I can:

for (i = 0; i < 15; i++)
{
sum_square += pow(count, 2.0);
}

You did not test this or you would have found that even the best
generators fail your Chi squared test!

It raises an odd question (now OT, so I don't plan to pursue it) but
why *test* the randomness at all? RH's code restricts the character
set, so if you found that it passed a test for random bit strings, you
would *know* that test was not good enough. Looks like coding for the
sake of it.

On the subject in hand, I think RH's definition of the problem is a
perfectly good one (considering the lack of detail about the OP
required). To measure it against a test it is bound to fail is rather
perverse.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,431
Messages
2,571,678
Members
48,796
Latest member
Greg L.

Latest Threads

Top