C语言版密码锁

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

#define MAX_PASSWORD_LEN 100
#define ENCRYPTED_LEN (MAX_PASSWORD_LEN * 8 + 1)

// 加密密码:每个字符ASCII+5后转为8位二进制
void encrypt_password(const char *password, char *encrypted) {
    int pos = 0;
    for (int i = 0; password[i] != '\0'; i++) {
        unsigned char c = password[i] + 5;
        for (int j = 7; j >= 0; j--) {
            encrypted[pos++] = (c & (1 << j)) ? '1' : '0';
        }
    }
    encrypted[pos] = '\0';
}

// 解密密码:二进制转ASCII后-5
int decrypt_password(const char *encrypted, char *password) {
    int len = strlen(encrypted);
    if (len % 8 != 0) return -1;
    int num_chars = len / 8;
    for (int i = 0; i < num_chars; i++) {
        unsigned char c = 0;
        for (int j = 0; j < 8; j++) {
            c <<= 1;
            if (encrypted[i*8 + j] == '1') c |= 1;
        }
        password[i] = c - 5;
    }
    password[num_chars] = '\0';
    return 0;
}

// 读取配置文件
void read_config(char *encrypted, int *lock_enabled) {
    FILE *fp = fopen("config.txt", "r");
    if (!fp) {
        strcpy(encrypted, "001101100011011100111000001110010011101000111011");
        *lock_enabled = 1;
        return;
    }
    if (!fgets(encrypted, ENCRYPTED_LEN, fp)) {
        strcpy(encrypted, "001101100011011100111000001110010011101000111011");
        *lock_enabled = 1;
        fclose(fp);
        return;
    }
    encrypted[strcspn(encrypted, "\n")] = '\0';
    char line[16];
    *lock_enabled = 1;
    if (fgets(line, sizeof(line), fp)) sscanf(line, "%d", lock_enabled);
    fclose(fp);
}

// 写入配置文件
void write_config(const char *encrypted, int lock_enabled) {
    FILE *fp = fopen("config.txt", "w");
    if (!fp) {
        perror("保存失败");
        return;
    }
    fprintf(fp, "%s\n%d\n", encrypted, lock_enabled);
    fclose(fp);
}

void settings_menu();

// 主菜单
void main_menu() {
    int choice;
    while (1) {
        printf("\n主菜单\n1.设置\n2.退出\n请选择: ");
        scanf("%d", &choice);
        getchar();
        switch (choice) {
            case 1: settings_menu(); break;
            case 2: exit(0);
            default: printf("无效选项\n");
        }
    }
}

// 切换密码锁状态
void toggle_lock() {
    char encrypted[ENCRYPTED_LEN];
    int lock_enabled;
    read_config(encrypted, &lock_enabled);
    lock_enabled = !lock_enabled;
    write_config(encrypted, lock_enabled);
    printf("密码锁已%s\n", lock_enabled ? "开启" : "关闭");
}

// 修改密码
void change_password() {
    char encrypted[ENCRYPTED_LEN];
    int lock_enabled;
    read_config(encrypted, &lock_enabled);
    
    char current_password[MAX_PASSWORD_LEN + 1];
    if (decrypt_password(encrypted, current_password) != 0) {
        printf("密码解析失败!\n");
        return;
    }

    int attempts = 0;
    char input[MAX_PASSWORD_LEN + 1];
    while (attempts < 3) {
        printf("请输入原密码: ");
        fgets(input, sizeof(input), stdin);
        input[strcspn(input, "\n")] = '\0';
        if (strcmp(input, current_password) == 0) break;
        printf("密码错误,剩余次数: %d\n", 2 - attempts++);
    }
    if (attempts >= 3) {
        printf("验证失败!\n");
        return;
    }

    char new_password[MAX_PASSWORD_LEN + 1], confirm[sizeof(new_password)];
    printf("输入新密码: ");
    fgets(new_password, sizeof(new_password), stdin);
    new_password[strcspn(new_password, "\n")] = '\0';
    printf("确认新密码: ");
    fgets(confirm, sizeof(confirm), stdin);
    confirm[strcspn(confirm, "\n")] = '\0';

    if (strcmp(new_password, confirm) {
        printf("两次输入不一致!\n");
        return;
    }

    char new_encrypted[ENCRYPTED_LEN];
    encrypt_password(new_password, new_encrypted);
    write_config(new_encrypted, lock_enabled);
    printf("密码修改成功!\n");
}

// 设置菜单
void settings_menu() {
    int choice;
    while (1) {
        printf("\n设置菜单\n1.切换密码锁\n2.修改密码\n3.返回\n请选择: ");
        scanf("%d", &choice);
        getchar();
        switch (choice) {
            case 1: toggle_lock(); break;
            case 2: change_password(); break;
            case 3: return;
            default: printf("无效选项\n");
        }
    }
}

int main() {
    char encrypted[ENCRYPTED_LEN];
    int lock_enabled;
    read_config(encrypted, &lock_enabled);

    if (lock_enabled) {
        char current_password[MAX_PASSWORD_LEN + 1];
        if (decrypt_password(encrypted, current_password) != 0) {
            printf("使用默认密码123456\n");
            strcpy(current_password, "123456");
        }

        int attempts = 0;
        while (attempts < 3) {
            printf("请输入密码: ");
            char input[MAX_PASSWORD_LEN + 1];
            fgets(input, sizeof(input), stdin);
            input[strcspn(input, "\n")] = '\0';
            if (strcmp(input, current_password) == 0) break;
            printf("密码错误,剩余次数: %d\n", 2 - attempts++);
        }
        if (attempts >= 3) {
            printf("超过尝试次数,程序退出!\n");
            return 0;
        }
    }

    main_menu();
    return 0;
}

运行结果: 

 

代码说明

  1. 加密与解密

    • encrypt_password函数将每个字符的ASCII码加5后转换为8位二进制字符串。

    • decrypt_password函数将二进制字符串转换回ASCII码并减5得到原始密码。

  2. 配置文件处理

    • read_config读取配置文件,获取加密密码和密码锁状态,若文件不存在则使用初始密码。

    • write_config将当前密码和状态写入配置文件。

  3. 主流程

    • 程序启动时检查密码锁状态,若开启则验证密码(最多3次错误)。

    • 主菜单提供设置和退出选项,设置菜单可切换密码锁状态或修改密码。

  4. 修改密码

    • 修改密码时需要先验证原密码(3次机会),确认新密码一致性后加密保存。

  5. 安全性处理

    • 密码存储时进行加密处理,避免明文存储。

    • 输入密码时隐藏显示(未实现,可按需求扩展)。

该程序实现了题目要求的所有功能,并通过文件存储保持配置的持久化。

注:

1.题目来源优快云@Citrus-1120

2.初始密码为123456(可自行设置)

要安装Docker并安装插件,可以按照以下步骤进行操作: 1. 首先,安装Docker。可以按照官方文档提供的步骤进行安装,或者使用适合您操作系统的包管理器进行安装。 2. 安装Docker Compose插件。可以使用以下方法安装: 2.1 下载指定版本的docker-compose文件: curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose 2.2 赋予docker-compose文件执行权限: chmod +x /usr/local/bin/docker-compose 2.3 验证安装是否成功: docker-compose --version 3. 在安装插件之前,可以测试端口是否已被占用,以避免编排过程中出错。可以使用以下命令安装netstat并查看端口号是否被占用: yum -y install net-tools netstat -npl | grep 3306 现在,您已经安装了Docker并安装了Docker Compose插件,可以继续进行其他操作,例如上传docker-compose.yml文件到服务器,并在服务器上安装MySQL容器。可以参考Docker的官方文档或其他资源来了解如何使用Docker和Docker Compose进行容器的安装和配置。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Docker安装docker-compose插件](https://blog.youkuaiyun.com/qq_50661854/article/details/124453329)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [Docker安装MySQL docker安装mysql 完整详细教程](https://blog.youkuaiyun.com/qq_40739917/article/details/130891879)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

myxixilovek

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值