一、前言
为了防止机器人或脚本程序自动化攻击和滥用系统资源,很多网站和应用程序需要使用验证码来判断用户是否为真人。 一般登录都要求用户手动输入以验证身份的安全措施。验证码是一种通过生成包含随机字符的图像或文本,通常包含了不同大小写字母、数字或特殊符号,具有一定的复杂性和随机性,使机器难以识别和破解。
本项目使用 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; // RimageData[i + 1] = 255; // GimageData[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
函数开始人机验证。当用户输入结果后,程序给出验证结果。