#2
吹水佬2023-04-23 17:17
|
遇到的问题是该段标注区域会多一次的纪录,不知道是什么地方出问题。
程式码与图片如下#
只有本站会员才能查看附件,请 登录
程序代码:
#include <stdio.h>
#include <windows.h>
#define MAX_KEYS 30
#define MAX_KEYSB 30
#define MAX_INTERVALS (MAX_KEYS - 1)
#define MAX_INTERVALSB (MAX_KEYSB - 1)// 設定驗證密碼紀錄的間隔數比輸入按鍵少一
int main()
{
INPUT_RECORD input_record;
HANDLE console = GetStdHandle(STD_INPUT_HANDLE);
DWORD events_read; // DWORD變量: 事件讀取(記錄按鍵按下的時間和釋放的時間)
LARGE_INTEGER start_time, end_time, frequency;
BOOL last_event_was_release = FALSE;
LARGE_INTEGER last_release_time;
int key_count = 0;
double sum, avg;
char keys[MAX_KEYS] = { 0 };
char keysB[MAX_KEYSB] = { 0 };
double intervals[MAX_INTERVALS - 1] = { 0 };
double intervalsB[MAX_INTERVALSB - 1] = { 0 };// 設定陣列紀錄間隔數組
double intervaldifferent;
char input[20]; // 儲存使用者輸入的字串
char target[] = "password"; // 設定目標字串
int flag = 1;
QueryPerformanceFrequency(&frequency);
printf("請設定節拍密碼\n\n");
while (1) {
if (ReadConsoleInput(console, &input_record, 1, &events_read)) { //讀取控制台輸入(console是正在讀取的控制台輸入緩衝區的句柄,&input_record是指向緩衝區的指針,該緩衝區接收讀取的輸入記錄,1是要讀取的輸入記錄數,&events_read是一個指向變量的指針,該變量接收實際讀取的輸入記錄數)
if (input_record.EventType == KEY_EVENT) { //檢查輸入記錄的事件類型是否為鍵盤事件
if (input_record.Event.KeyEvent.bKeyDown) { //檢查鍵是否被按下。如果此條件為真,代碼將執行 if 語句內的代碼塊
if (last_event_was_release && input_record.Event.KeyEvent.wVirtualKeyCode != VK_RETURN) { //檢查上一個事件是否為按鍵釋放以及當前事件是否為按鍵(不包括回車鍵)
LARGE_INTEGER press_time;
QueryPerformanceCounter(&press_time); //記錄按鍵事件的時間
double intervalA = (double)(press_time.QuadPart - last_release_time.QuadPart) / frequency.QuadPart * 1.0; //併計算按鍵與最後一次按鍵釋放事件之間的間隔
intervals[key_count - 1] = intervalA; // 將間隔存儲在適當索引 (key_count - 1) 的間隔數組中
printf("上下按鍵的時間間隔(節奏): %.3fs\n", (double)(press_time.QuadPart - last_release_time.QuadPart) / frequency.QuadPart * 1.0); //將間隔打印到控制台。打印的消息包括按鍵和最後一次按鍵釋放事件之間的時間間隔(以秒為單位)
}
QueryPerformanceCounter(&start_time); //用於獲取性能計數器的值,該值存儲在start_time變量中,然後用於計算按鍵按下和按鍵釋放之間經過的時間。
last_event_was_release = FALSE; //設置FALSE為表示最後一個事件是按鍵,這是計算節奏中按鍵之間的間隔所需要的。
if (key_count < MAX_KEYS) {
keys[key_count++] = input_record.Event.KeyEvent.uChar.AsciiChar;
}
}
else {
LARGE_INTEGER release_time;
QueryPerformanceCounter(&release_time);
last_release_time = release_time;
last_event_was_release = TRUE;
if (input_record.Event.KeyEvent.uChar.AsciiChar != '\0') {
printf("'%c'\n", input_record.Event.KeyEvent.uChar.AsciiChar);
}
else {
printf("Key pressed for %.3f s\n", (release_time.QuadPart - start_time.QuadPart) / frequency.QuadPart * 1.0);
}
}
}
}
// 如果Enter鍵被按下,跳出設定密碼
if (GetAsyncKeyState(VK_RETURN) & 1) {
printf("\n==============================================================================\n");
printf("再輸入一次節拍密碼\n\n");
int key_countB = 0;
while (2) {
if (ReadConsoleInput(console, &input_record, 1, &events_read)) { //讀取控制台輸入(console是正在讀取的控制台輸入緩衝區的句柄,&input_record是指向緩衝區的指針,該緩衝區接收讀取的輸入記錄,1是要讀取的輸入記錄數,&events_read是一個指向變量的指針,該變量接收實際讀取的輸入記錄數)
if (input_record.EventType == KEY_EVENT) { //檢查輸入記錄的事件類型是否為鍵盤事件
if (input_record.Event.KeyEvent.bKeyDown) { //檢查鍵是否被按下。如果此條件為真,代碼將執行 if 語句內的代碼塊
if (last_event_was_release && input_record.Event.KeyEvent.wVirtualKeyCode != VK_RETURN) { //檢查上一個事件是否為按鍵釋放以及當前事件是否為按鍵(不包括回車鍵)
LARGE_INTEGER press_time;
QueryPerformanceCounter(&press_time); //記錄按鍵事件的時間
double intervalA = (double)(press_time.QuadPart - last_release_time.QuadPart) / frequency.QuadPart * 1.0; //併計算按鍵與最後一次按鍵釋放事件之間的間隔
intervalsB[key_countB - 1] = intervalA; // 將間隔存儲在適當索引 (key_count - 1) 的間隔數組中
printf("上下按鍵的時間間隔(節奏): %.3fs\n", (double)(press_time.QuadPart - last_release_time.QuadPart) / frequency.QuadPart * 1.0); //將間隔打印到控制台。打印的消息包括按鍵和最後一次按鍵釋放事件之間的時間間隔(以秒為單位)
}
QueryPerformanceCounter(&start_time); //用於獲取性能計數器的值,該值存儲在start_time變量中,然後用於計算按鍵按下和按鍵釋放之間經過的時間。
last_event_was_release = FALSE; //設置FALSE為表示最後一個事件是按鍵,這是計算節奏中按鍵之間的間隔所需要的。
if (key_countB < MAX_KEYS) {
keysB[key_countB++] = input_record.Event.KeyEvent.uChar.AsciiChar;
}
}
else {
LARGE_INTEGER release_time;
QueryPerformanceCounter(&release_time);
last_release_time = release_time;
last_event_was_release = TRUE;
if (input_record.Event.KeyEvent.uChar.AsciiChar != '\0') {
printf("'%c' 鍵被按下\n", input_record.Event.KeyEvent.uChar.AsciiChar);
}
else {
printf("Key pressed for %.3f s\n", (release_time.QuadPart - start_time.QuadPart) / frequency.QuadPart * 1.0);
}
}
}
}
// 如果Enter鍵被按下,跳出設定密碼
if (GetAsyncKeyState(VK_RETURN) & 1) {
int i = 0;
for (int i = 0; i < key_count; i++) {
if (keys[i] != keysB[i])
{
printf("密碼數字設定錯誤\n");
}
else {
printf("密碼數字設定正確\n");
}
}
for (int i = 0; i < key_count - 1; i++) {
intervaldifferent = intervals[i] - intervalsB[i];
if (intervaldifferent < 0) {
intervaldifferent = intervaldifferent * (-1);
}
if (intervaldifferent > 0.25 * intervals[i])
{
printf("密碼數字間隔錯誤\n");
}
else {
printf("密碼數字間隔正確\n");
}
}
break;
}
}
break;
}
}
return 0;
}
/*
*/