为了防止机器人或脚本程序自动化攻击和滥用系统资源,很多网站和应用程序需要使用验证码来判断用户是否为真人。 一般登录都要求用户手动输入以验证身份的安全措施。验证码是一种通过生成包含随机字符的图像或文本,通常包含了不同大小写字母、数字或特殊符号,具有一定的复杂性和随机性,使机器难以识别和破解。
本项目使用 C 语言实现一个简单的人机验证码生成和验证程序。程序生成一个由4位随机字符组成的验证码,并要求用户在控制台中手动输入该验证码。如果用户输入与生成的验证码匹配,则输出"验证成功";否则输出"验证失败"。
在生成验证码的过程中,使用了随机数生成函数 rand()
来获取随机数,并结合字符集合来生成随机字符。为了确保每次生成的验证码都是独一无二的,使用当前系统时间作为种子来初始化随机数生成器。
这个项目可以应用于各种需求,如注册页面的人机验证、防止暴力破解密码的登录页面、限制自动化爬虫等。通过要求用户手动输入验证码,可以有效防止机器人或脚本程序的自动化攻击,提高系统安全性和用户隐私保护。
下面给了3种例子,分别是字符验证码
、图片验证码
、计算题结果验证
。
#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
函数比较用户输入的验证码和生成的验证码,如果相等则输出"验证成功",否则输出"验证失败"。
#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图片中,在控制台打印出验证码和生成的图片文件名。
#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
函数开始人机验证。当用户输入结果后,程序给出验证结果。