逐梦者
逐梦者

使用内联汇编调用CPU内置真随机数发生器试验

#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;
}
https://www.xnpu.top/wp-content/uploads/2025/09/pseudo_random_color.png
https://www.xnpu.top/wp-content/uploads/2025/09/true_random_bw.png
https://www.xnpu.top/wp-content/uploads/2025/09/true_random_color.png
https://www.xnpu.top/wp-content/uploads/2025/09/pseudo_random_bw.png
没有标签
首页      未分类      使用内联汇编调用CPU内置真随机数发生器试验

发表回复

textsms
account_circle
email

Captcha Code

逐梦者

使用内联汇编调用CPU内置真随机数发生器试验
#include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <time.h> // 检查CPU是否支持RDRAND指令 int check_rdrand_support() {     unsig…
扫描二维码继续阅读
2025-09-09