Small program to generate random bytes to stdout, using original 2008 randombytes() function that presumably inspired librandombytes.<p>Usage:<p><pre><code> a.out number_of_bytes
</code></pre>
For example,<p><pre><code> a.out 128 > data
od -tx1 -An < data
</code></pre>
Taken from public domain source code by djb and jmojzis. Tested on Void Linux with musl.<p><pre><code> #include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <poll.h>
#include <errno.h>
#include <sys/stat.h>
int strtonum(long long *,const char *);
int strtonum(long long *r,const char *buf){
char *bufpos=(char *)buf;
int flagsign=0;
long long i;
unsigned long long c,ret=0;
if (!buf) goto failed;
switch(buf[0]){
case 0: goto failed;break;
case '+': ++bufpos;break;
case '-': flagsign=1;++bufpos;break;
default: break;
}
for(i=0;bufpos[i];++i){
c=bufpos[i]-'0';
if(c<0||c>9)break;
c+=10*(ret);
if(ret>c)goto failed;
ret=c;
}
if(i==0)goto failed;
if(flagsign){*r=-ret;if(*r>0)goto failed;}
else{*r=ret;if(*r<0)goto failed;}
return 1;
failed:
*r=0;
errno=EINVAL;
return 0;
}
int writeall(int,const void *,long long);
int writeall(int fd,const void *xv,long long xlen)
{
const unsigned char *x=xv;
long long w;
while(xlen>0){
w=xlen;
if(w>1048576)w=1048576;
w=write(fd,x,w);
if(w<0){
if(errno==EINTR||errno==EAGAIN||errno==EWOULDBLOCK){
struct pollfd p;p.fd=fd;p.events=POLLOUT|POLLERR;
poll(&p,1,-1);continue;
}
return -1;
}
x += w;
xlen -= w;
}
return 0;
}
void randombytes(unsigned char *,unsigned long long);
/* it's really stupid that there isn't a syscall for this */
static int fd = -1;
void randombytes(unsigned char *x,unsigned long long xlen)
{
int i;
if(fd==-1){
for(;;){
fd=open("/dev/urandom",O_RDONLY);
if(fd!=-1)break;
sleep(1);
}
}
while(xlen>0){
if(xlen<1048576)i=xlen;else i=1048576;
i=read(fd,x,i);
if(i<1){sleep(1);continue;}
x+=i;xlen-=i;
}
}
int fsyncfd(int);
int fsyncfd(int fd){
struct stat st;
if(fstat(fd,&st)==0&&S_ISREG(st.st_mode)){
if(fsync(fd)==-1)return -1;}
return 0;
}
void byte_zero(void *,long long);
void byte_zero(void *yv,long long ylen){
long long i;char *y=yv;
for(i=0;i<ylen;++i)y[i]=0;
}
static unsigned char buf[4096];
int main(int argc,char **argv){
long long i,l;
if(!strtonum(&l,argv[1])||l<0)exit(0);
byte_zero(buf,sizeof buf);
while(l>0){
i=l;
if(i>sizeof buf)i=sizeof buf;
randombytes(buf,i);
if(writeall(1,buf,i)==-1)exit(0);
l-=i;
}
if(fsyncfd(1)==-1)exit(0);
exit(0);
}</code></pre>