前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >人机验证码生成与验证:提升系统安全性

人机验证码生成与验证:提升系统安全性

作者头像
DS小龙哥
发布2023-12-28 09:11:04
1820
发布2023-12-28 09:11:04
举报

一、前言

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

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

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

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

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

image.png
image.png
image-20230816101944251
image-20230816101944251
image-20230816101926767
image-20230816101926767

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

代码语言:javascript
复制
#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 函数比较用户输入的验证码和生成的验证码,如果相等则输出"验证成功",否则输出"验证失败"。

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

代码语言:javascript
复制
#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图片中,在控制台打印出验证码和生成的图片文件名。

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

代码语言:javascript
复制
#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函数开始人机验证。当用户输入结果后,程序给出验证结果。

image.png
image.png
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-12-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、前言
  • 二、代码实现(生成验证码并进行验证)
  • 三、生成验证码,绘制到图片里,提高验证难度
  • 四、通过生成随机计算题来测试,提高验证难度
相关产品与服务
验证码
腾讯云新一代行为验证码(Captcha),基于十道安全栅栏, 为网页、App、小程序开发者打造立体、全面的人机验证。最大程度保护注册登录、活动秒杀、点赞发帖、数据保护等各大场景下业务安全的同时,提供更精细化的用户体验。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档