#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <time.h>
// 检查CPU是否支持RDRAND指令
int check_rdrand_support() {
unsigned int eax, ebx, ecx, edx;
eax = 1; // 功能号1用于获取处理器特性
__asm__ __volatile__ (
"cpuid"
: "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx)
: "a"(eax)
);
// 检查ECX寄存器的第30位(RDRAND支持位)
return (ecx & (1 << 30)) != 0;
}
// 使用RDRAND指令生成32位随机数(真随机数)
int rdrand32(uint32_t *rand) {
unsigned char ok;
unsigned int retries = 10;
do {
__asm__ __volatile__ (
"rdrand %0; setc %1"
: "=r"(*rand), "=qm"(ok)
);
if (ok) return 1;
} while (retries--);
return 0;
}
// 使用C标准库生成伪随机数
uint32_t pseudo_rand32() {
return (uint32_t)rand();
}
// 生成真随机数彩色点阵图
void generate_true_random_color(const char *filename, int width, int height) {
FILE *fp = fopen(filename, "wb");
if (!fp) {
printf("无法创建文件: %s\n", filename);
return;
}
fprintf(fp, "P6\n%d %d\n255\n", width, height);
uint32_t rand_val;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
if (rdrand32(&rand_val)) {
unsigned char r = (rand_val) & 0xFF;
unsigned char g = (rand_val >> 8) & 0xFF;
unsigned char b = (rand_val >> 16) & 0xFF;
fputc(r, fp);
fputc(g, fp);
fputc(b, fp);
} else {
fputc(0, fp);
fputc(0, fp);
fputc(0, fp);
}
}
}
fclose(fp);
printf("已生成真随机数彩色点阵图: %s\n", filename);
}
// 生成伪随机数彩色点阵图
void generate_pseudo_random_color(const char *filename, int width, int height) {
FILE *fp = fopen(filename, "wb");
if (!fp) {
printf("无法创建文件: %s\n", filename);
return;
}
fprintf(fp, "P6\n%d %d\n255\n", width, height);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
uint32_t rand_val = pseudo_rand32();
unsigned char r = (rand_val) & 0xFF;
unsigned char g = (rand_val >> 8) & 0xFF;
unsigned char b = (rand_val >> 16) & 0xFF;
fputc(r, fp);
fputc(g, fp);
fputc(b, fp);
}
}
fclose(fp);
printf("已生成伪随机数彩色点阵图: %s\n", filename);
}
// 生成真随机数黑白点阵图
void generate_true_random_bw(const char *filename, int width, int height) {
FILE *fp = fopen(filename, "wb");
if (!fp) {
printf("无法创建文件: %s\n", filename);
return;
}
fprintf(fp, "P6\n%d %d\n255\n", width, height);
uint32_t rand_val;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
if (rdrand32(&rand_val)) {
unsigned char color = (rand_val & 1) ? 255 : 0;
fputc(color, fp);
fputc(color, fp);
fputc(color, fp);
} else {
fputc(128, fp);
fputc(128, fp);
fputc(128, fp);
}
}
}
fclose(fp);
printf("已生成真随机数黑白点阵图: %s\n", filename);
}
// 生成伪随机数黑白点阵图
void generate_pseudo_random_bw(const char *filename, int width, int height) {
FILE *fp = fopen(filename, "wb");
if (!fp) {
printf("无法创建文件: %s\n", filename);
return;
}
fprintf(fp, "P6\n%d %d\n255\n", width, height);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
uint32_t rand_val = pseudo_rand32();
unsigned char color = (rand_val & 1) ? 255 : 0;
fputc(color, fp);
fputc(color, fp);
fputc(color, fp);
}
}
fclose(fp);
printf("已生成伪随机数黑白点阵图: %s\n", filename);
}
int main() {
printf("真随机数与伪随机数点阵图对比程序\n");
// 初始化伪随机数生成器
srand(time(NULL));
int has_rdrand = check_rdrand_support();
if (has_rdrand) {
printf("CPU支持RDRAND指令,将生成真随机数点阵图\n");
// 生成真随机数点阵图
generate_true_random_color("true_random_color.ppm", 512, 512);
generate_true_random_bw("true_random_bw.ppm", 512, 512);
} else {
printf("警告: 当前CPU不支持RDRAND指令,只生成伪随机数点阵图\n");
}
// 生成伪随机数点阵图
generate_pseudo_random_color("pseudo_random_color.ppm", 512, 512);
generate_pseudo_random_bw("pseudo_random_bw.ppm", 512, 512);
printf("\n点阵图生成完成。请使用图像查看器打开生成的.ppm文件进行对比。\n");
printf("\n观察要点:\n");
printf("1. 真随机数点阵图应该像电视静态噪声,没有可见模式\n");
printf("2. 伪随机数点阵图可能显示条纹、重复模式或周期性结构\n");
printf("3. 黑白点阵图更容易检测细微的模式\n");
printf("4. 彩色点阵图可以检查颜色分布是否均匀\n");
if (has_rdrand) {
printf("\n对比建议:\n");
printf("- 比较 true_random_color.ppm 和 pseudo_random_color.ppm\n");
printf("- 比较 true_random_bw.ppm 和 pseudo_random_bw.ppm\n");
printf("- 注意观察伪随机数图像中是否有重复模式或条纹\n");
}
return 0;
}
发表回复