C语言实例_生成随机验证码判断人机

一、前言

为了防止机器人或脚本程序自动化攻击和滥用系统资源,很多网站和应用程序需要使用验证码来判断用户是否为真人。 一般登录都要求用户手动输入以验证身份的安全措施。验证码是一种通过生成包含随机字符的图像或文本,通常包含了不同大小写字母、数字或特殊符号,具有一定的复杂性和随机性,使机器难以识别和破解。

本项目使用 C 语言实现一个简单的人机验证码生成和验证程序。程序生成一个由4位随机字符组成的验证码,并要求用户在控制台中手动输入该验证码。如果用户输入与生成的验证码匹配,则输出"验证成功";否则输出"验证失败"。

在生成验证码的过程中,使用了随机数生成函数 rand() 来获取随机数,并结合字符集合来生成随机字符。为了确保每次生成的验证码都是独一无二的,使用当前系统时间作为种子来初始化随机数生成器。

这个项目可以应用于各种需求,如注册页面的人机验证、防止暴力破解密码的登录页面、限制自动化爬虫等。通过要求用户手动输入验证码,可以有效防止机器人或脚本程序的自动化攻击,提高系统安全性和用户隐私保护。

下面给了3种例子,分别是字符验证码图片验证码计算题结果验证

二、代码实现(生成验证码并进行验证)

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
​
// 生成随机验证码
void generateCode(char* code, int length) {
    const char charset[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    srand(time(NULL));
​
    for (int i = 0; i < length; i++) {
        int index = rand() % (sizeof(charset) - 1);
        code[i] = charset[index];
    }
​
    code[length] = '\0';
}
​
int main() {
    char code[5];
    generateCode(code, 4);
    printf("请输入验证码:%s\n", code);
​
    char input[5];
    scanf("%s", input);
​
    if (strcmp(input, code) == 0) {
        printf("验证成功!\n");
    } else {
        printf("验证失败!\n");
    }
​
    return 0;
}
​

代码中,generateCode 函数用于生成指定长度的随机验证码。使用包含大小写字母和数字的字符集合,通过调用 srand() 函数设置随机数种子,确保每次生成的验证码都是不同的。

main 函数中,调用 generateCode 生成一个4位数的验证码,将其打印出来。用户输入验证码,输入结果存储在 input 字符数组中。

通过使用 strcmp 函数比较用户输入的验证码和生成的验证码,如果相等则输出"验证成功",否则输出"验证失败"。

三、生成验证码,绘制到图片里,提高验证难度

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#pragma warning(disable:4996)

#define WIDTH 50    // 图片宽度
#define HEIGHT 50   // 图片高度

// 生成随机4位数验证码
int generateRandomCode() {
    srand(time(NULL));
    return rand() % 10000;
}

// 绘制验证码到BMP图片
void drawCodeToBMP(int code) {
    FILE* filePtr;
    unsigned char* imageData;
    int imageSize = WIDTH * HEIGHT * 3;  // 3 bytes per pixel (RGB)
    
    // 分配内存用于存储图像数据
    imageData = (unsigned char*)malloc(imageSize);
    
    // 设置所有像素为白色
    for (int i = 0; i < imageSize; i += 3) {
        imageData[i] = 255;     // R
        imageData[i + 1] = 255; // G
        imageData[i + 2] = 255; // B
    }
    
    // 在图像中心绘制验证码
    int x = (WIDTH / 2) - 10;   // x坐标偏移量,使验证码居中显示
    int y = (HEIGHT / 2) + 5;   // y坐标偏移量,使验证码居中显示
    sprintf((char*)(imageData + ((y * WIDTH + x) * 3)), "%04d", code);
    
    // 打开文件准备写入图像数据
    filePtr = fopen("6666.bmp", "wb");
    
    // BMP文件头
    unsigned char bmpFileHeader[] = {
        0x42, 0x4D,             // 文件类型
        0x36, 0x00, 0x0C, 0x00, // 文件大小
        0x00, 0x00,             // 保留字
        0x00, 0x00,             // 保留字
        0x36, 0x00, 0x00, 0x00, // 数据偏移量
    };
    
    // BMP信息头
    unsigned char bmpInfoHeader[] = {
        0x28, 0x00, 0x00, 0x00, // 信息头大小
        0x32, 0x00, 0x00, 0x00, // 图像宽度
        0x32, 0x00, 0x00, 0x00, // 图像高度
        0x01, 0x00,             // 颜色平面数
        0x18, 0x00,             // 每像素位数
        0x00, 0x00, 0x00, 0x00, // 压缩方式
        0x00, 0x00, 0x0C, 0x00, // 图像数据大小
        0x00, 0x00, 0xC4, 0x0E, // 水平分辨率
        0x00, 0x00, 0xC4, 0x0E, // 垂直分辨率
        0x00, 0x00, 0x00, 0x00, // 颜色表数目
        0x00, 0x00, 0x00, 0x00, // 重要颜色数目
    };
    
    // 写入文件头和信息头
    fwrite(bmpFileHeader, sizeof(unsigned char), sizeof(bmpFileHeader), filePtr);
    fwrite(bmpInfoHeader, sizeof(unsigned char), sizeof(bmpInfoHeader), filePtr);
    
    // 写入图像数据
    fwrite(imageData, sizeof(unsigned char), imageSize, filePtr);
    
    // 关闭文件
    fclose(filePtr);
    
    // 释放内存
    free(imageData);
}

int main() {
    int code = generateRandomCode();
    
    printf("验证码: %04d\n", code);
    
    drawCodeToBMP(code);
    
    printf("已生成验证码图片: 6666.bmp\n");
    
    return 0;
}

generateRandomCode函数用于生成随机的4位数验证码。drawCodeToBMP函数根据验证码将其绘制在50x50像素大小的白色BMP图片中,将图像数据保存到名为6666.bmp的文件中。

main函数中,先生成一个随机的4位数验证码,通过调用drawCodeToBMP函数将验证码绘制到BMP图片中,在控制台打印出验证码和生成的图片文件名。

四、通过生成随机计算题来测试,提高验证难度

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#pragma warning(disable:4996)

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

// 生成随机运算题目
void generateRandomQuestion() {
    srand(time(NULL));
    int num1 = rand() % 20;  // 生成0到19的随机数
    int num2 = rand() % 20;
    char operators[3] = { '+', '-', 'x' };
    char op = operators[rand() % 3];  // 从加减乘中随机选择一个运算符

    printf("请计算以下题目的答案:\n");
    printf("%d %c %d = ?\n", num1, op, num2);

    // 验证用户输入的结果
    int userAnswer;
    scanf("%d", &userAnswer);

    int correctAnswer;
    switch (op) {
    case '+':
        correctAnswer = num1 + num2;
        break;
    case '-':
        correctAnswer = num1 - num2;
        break;
    case 'x':
        correctAnswer = num1 * num2;
        break;
    default:
        break;
    }

    if (userAnswer == correctAnswer) {
        printf("验证成功!\n");
    }
    else {
        printf("验证失败,正确答案是:%d\n", correctAnswer);
    }
}

int main() {
    printf("欢迎来到人机验证系统!\n");
    printf("请计算下面的题目,并输入答案。\n");

    generateRandomQuestion();

    return 0;
}

generateRandomQuestion函数中生成两个0到19的随机整数和一个随机的加减乘运算符,打印出题目要求用户计算结果。通过scanf函数获取用户输入的结果,与程序计算得到的正确结果进行比较,最终输出验证成功或失败的信息。

main函数中,调用generateRandomQuestion函数开始人机验证。当用户输入结果后,程序给出验证结果。

相关推荐
止语Lab1 小时前
好的 DX 不等于少写代码——三种语言的摩擦力设计课
后端
吃饱了得干活1 小时前
别再手动解析 LLM 输出了!LangChain 四种结构化输出方案对比
后端·python·langchain
程序员天天困1 小时前
Arthas trace 命令怎么用?一行定位最慢那行代码
jvm·后端
Huiturn1 小时前
GPT 5.6 连续编码 10 小时,纯 Python 啃下 Word 二进制格式——doc2docx 实现拆解
后端
用户298698530141 小时前
Python 实现 Excel 与 Markdown 互转的实用指南
后端·python·excel
用户77283104908401 小时前
krono-job:零侵入、单二进制交付的分布式任务调度平台(开源)
后端
Conan在掘金1 小时前
鸿蒙报错速查:Function lacks ending return statement,返回路径漏 return 就炸,根因 + 真解法
后端
人间凡尔赛2 小时前
AI-Native 云原生架构:2026 年从容器编排到智能体编排的范式革命
后端·云原生·架构
IT_陈寒2 小时前
Vue的响应式让我加班到凌晨3点,原来问题出在这
前端·人工智能·后端
卷无止境2 小时前
提升 Python 代码健壮性的方法大盘点
后端·python