/*
ULISCAN.c --- 8 位块大小
1998 年 10 月1 日
1998 年 12 月 1 日
1998 年 12 月 21 日 uliscan.c 源自 ueli8.c
该版本已去除 // 注释,以便于 Sun cc 编译器使用
该程序实现了 Ueli M Maurer 的 "随机比特生成器的通用统计测试",使用 L=8
接受命令行上的文件名;将结果和其他信息写入标准输出(stdout)。
能够优雅地处理输入文件耗尽的情况。
参考文献:J. Cryptology v 5 no 2, 1992 页 89-105
也可以在某些网站上找到,那里是我找到它的地方。
-David Honig
honig@sprynet.com
用法:
ULISCAN 文件名
输出到标准输出(stdout)
*/
#define L 8
#define V (1<<L)
#define Q (10*V)
#define K (100 *Q)
#define MAXSAMP (Q + K)
#include <stdio.h>
#include <math.h>
int main(argc, argv)
int argc;
char **argv;
{
FILE *fptr;
int i,j;
int b, c;
int table[V];
double sum = 0.0;
int iproduct = 1;
int run;
extern double log(/* double x */);
printf("Uliscan 21 Dec 98 \nL=%d %d %d \n", L, V, MAXSAMP);
if (argc < 2) {
printf("Usage: Uliscan filename\n");
exit(-1);
} else {
printf("Measuring file %s\n", argv[1]);
}
fptr = fopen(argv[1],"rb");
if (fptr == NULL) {
printf("Can't find %s\n", argv[1]);
exit(-1);
}
for (i = 0; i < V; i++) {
table[i] = 0;
}
for (i = 0; i < Q; i++) {
b = fgetc(fptr);
table[b] = i;
}
printf("Init done\n");
printf("Expected value for L=8 is 7.1836656\n");
run = 1;
while (run) {
sum = 0.0;
iproduct = 1;
if (run)
for (i = Q; run && i < Q + K; i++) {
j = i;
b = fgetc(fptr);
if (b < 0)
run = 0;
if (run) {
if (table[b] > j)
j += K;
sum += log((double)(j-table[b]));
table[b] = i;
}
}
if (!run)
printf("Premature end of file; read %d blocks.\n", i - Q);
sum = (sum/((double)(i - Q))) / log(2.0);
printf("%4.4f ", sum);
for (i = 0; i < (int)(sum*8.0 + 0.50); i++)
printf("-");
printf("\n");
/*重新填充初始表格 */
if (0) {
for (i = 0; i < Q; i++) {
b = fgetc(fptr);
if (b < 0) {
run = 0;
} else {
table[b] = i;
}
}
}
}
}