标题:求求大佬帮忙,C语言想写一段节拍式的密码锁(包含密码设定/认证)
只看楼主
ianlin1024
Rank: 1
等 级:新手上路
帖 子:12
专家分:0
注 册:2023-3-11
结帖率:100%
已结贴  问题点数:20 回复次数:6 
求求大佬帮忙,C语言想写一段节拍式的密码锁(包含密码设定/认证)
想写一段节拍式的密码锁(包含密码设定/认证),流程与目前遇到的问题是

1.先输入若干数字(输入密码的节奏自行控制(ex. 1--2----3--4("-"为输入间隔(以ms表示))))
  遇到问题(1)不确定C语言是否能做到如"ex.",在只以数字键输入密码前提下,捕捉到其在输入的间隔时间并以某种形式记录下来
          (2)希望在键入密码的"同时"以声音做为提示音(类似提款机),目前是以<windows.h> 中的 Beep() 函数作为原型,但效果不理想(做不到同时的效果)

2.输入完成后按下enter进入到验证密码(使用者需照输入时的间隔节奏输入第一步设定的密码)
  遇到问题(1)希望输入密码时,将记录下的节奏加入+-的滞迟时间补偿(就如玩节奏游戏,不可能100%完全准确地按在节奏上,希望实现这种功能)

3.节奏与密码输入正确则显示正确提示(此用Password correct!表示)反之以Password incorrect!表示。
  遇到问题(1)还未能做到在验证密码"步骤2."让系统纪录时间差,故无法结合判断时间差(节奏)去做密码验证,目前程式码只能以密码是否正确作为验证(但这样失去设计本意),希望可以有解决办法

以上是目前遇到的技术瓶颈,自己在初次做这个项目有查阅很多资料,但几乎没有发现可行的解决办法,也许是基于C语言框架本身的限制,或着说我的观念还不太纯熟,提供这些,希望能提供一些帮助。

下面提供当初的程式码供参考:
程序代码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>
#include <conio.h>
#include <math.h>

const int NOTE = 440;

// 随机生成节奏和音高,并存储到对应的数组中
void generate_rhythm(int rhythm[], int durations[], int length)
{
    srand(time(NULL));

    for (int i = 0; i < length; i++)
    {
        rhythm[i] = rand() % 7;
        durations[i] = rand() % 1200 + 200;
    }
}

// 根据音高和持续时间,发出声音
void play_tone(int note_index, int duration)
{
    Beep(NOTE * (int)pow(2, note_index / 7.0), duration);
}

// 验证密码
int check_password(char password[], int rhythm[], int durations[], int length)
{
    int note_index = 0;

    printf("Please input the password in rhythm:n");

    for (int i = 0; i < length; i++)
    {
        char c = getch();

        if (c == 'r' || c == 'n' || c == ' ')
        {
            break;
        }

        if (password[i] != c)
        {
            return 0;
        }

        play_tone(rhythm[note_index], durations[note_index]);

        note_index = (note_index + 1) % length;

        Sleep(250);
    }

    return 1;
}

int main()
{
    char password[50];
    int rhythm[50], durations[50];
    int password_length = 0;

    generate_rhythm(rhythm, durations, 50);

    printf("Please enter your password:n");

    // 读入密码
    while (1)
    {
        char c = getch();

        if (c == 'r' || c == 'n')
        {
            break;
        }

        password[password_length] = c;
        password_length++;
    }

    // 发出节奏
    for (int i = 0; i < password_length; i++)
    {
        play_tone(rhythm[i], durations[i]);

        // 暂停一段时间,以实现特定的节奏
        Sleep(250);
    }

    // 验证密码
    if (check_password(password, rhythm, durations, password_length))
    {
        printf("nPassword correct!n");
    }
    else
    {
        printf("nPassword incorrect!n");
    }

    return 0;
}
搜索更多相关主题的帖子: int 输入 时间 password 密码 
2023-03-11 20:19
forever74
Rank: 12Rank: 12Rank: 12
来 自:CC
等 级:贵宾
威 望:49
帖 子:1636
专家分:3940
注 册:2007-12-27
得分:10 
不知道楼主有没有windows刚启动的一段时间系统对鼠标操作的响应不及时,出现明显滞后的体验。
这种体验告诉我们,不能在这个平台用软件实现1毫秒级时间精度,因为这个系统的进程切换就是毫秒级的,用户态层面的表现只能是“我尽量”,因而不存在精度较高的时间计量。
除非您架空了windows,把代码送到它下面去。

我的意思是您选错平台了。
用裸单片机做这个都能容易些。

对宇宙最严谨的描述应该就是宇宙其实是不严谨的
2023-03-11 21:04
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:507
帖 子:8890
专家分:53117
注 册:2011-1-18
得分:10 
纯C不行,你得调用操作系统提供的APIs,记录一下从键被按下到抬起的时间间隔。
控制台特有的用到三个函数,分别是
https://learn.
https://learn.
https://learn.

还可以用基于事件的,或快照的。太多了,自己Google
2023-03-11 21:14
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:507
帖 子:8890
专家分:53117
注 册:2011-1-18
得分:0 
回复 2楼 forever74
对,Windows不是实时系统,且一直用的是个55hz的定时器。
多媒体定时器虽然精度高一些,但Windows的系统调度本身不准时,且慢。
2023-03-11 21:19
ianlin1024
Rank: 1
等 级:新手上路
帖 子:12
专家分:0
注 册:2023-3-11
得分:0 
回复 3楼 rjsp
谢谢您,在听取您的建议之后尝试写出调用API的时间戳记显示出按键按下到释放的间隔时间!
但还未能写出每个按键释放后下一个按键按下时所花的时间。

希望将记录下来的时间用阵列形式记录下来方便取用数值

下面提供程式碼
程序代码:
#include <stdio.h>
#include <windows.h>

int main()
{
    INPUT_RECORD input_record;
    HANDLE console = GetStdHandle(STD_INPUT_HANDLE);
    DWORD events_read;
    LARGE_INTEGER start_time, end_time, frequency;
    BOOL first_event = TRUE;

    QueryPerformanceFrequency(&frequency);

    while (1) {
        if (ReadConsoleInput(console, &input_record, 1, &events_read)) {
            if (input_record.EventType == KEY_EVENT) {
                if (input_record.Event.KeyEvent.bKeyDown) {
                    if (first_event) {
                        QueryPerformanceCounter(&start_time);
                        first_event = FALSE;
                    }
                } else {
                    LARGE_INTEGER release_time;
                    QueryPerformanceCounter(&release_time);
                    first_event = TRUE;
                    if (input_record.Event.KeyEvent.uChar.AsciiChar != '\0') {
                        printf("'%c' key pressed for %.3f s\n", input_record.Event.KeyEvent.uChar.AsciiChar,
                            (double)(release_time.QuadPart - start_time.QuadPart) / frequency.QuadPart * 1.0);
                    } else {
                        printf("Key pressed for %.3f s\n", (release_time.QuadPart - start_time.QuadPart) / frequency.QuadPart * 1.0);
                    }
                }
            }
        }
    }

    return 0;
}


[此贴子已经被作者于2023-3-12 01:05编辑过]

2023-03-12 01:04
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:507
帖 子:8890
专家分:53117
注 册:2011-1-18
得分:0 
你是要获得 '1'键从按下到抬起的间隔时长,
还是 '1'键按下后 到 另一键按下时 的间隔时长?
2023-03-12 15:46
ianlin1024
Rank: 1
等 级:新手上路
帖 子:12
专家分:0
注 册:2023-3-11
得分:0 
回复 6楼 rjsp
谢谢您,我是想记录从按键放开(释放)到下一个按键按下的间隔时间。
目前统整之后可以实现上述的功能,目前正积极开发一开始所说的其他功能。

这边放上用illustrator简单绘制的示意图#


[此贴子已经被作者于2023-3-12 18:45编辑过]

2023-03-12 18:44



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-511515-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.377393 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved