检查密码符合C中的特定格式

9o685dep  于 2023-10-16  发布在  其他
关注(0)|答案(3)|浏览(95)

我正在用C语言创建一个密码检查器。用户输入他们的密码,程序必须检查它是否符合格式aa$B1BB$B$$aB(其中a代表数字,B代表符号,$代表数字)。
我目前已经编写了一个数字数组09,符号和字母,并试图创建一系列迭代循环来搜索密码的每个字符,以匹配它应该满足的标准数组。这是我想到的最简单的方法,但如果有人有更好的建议,我会非常感激。
我目前面临的错误是,程序没有像我预期的那样运行。如果密码不是13个字符长,它应该调用else if语句,但它没有。到目前为止,我只创建了用于检查数字1234的语句。printf("Password ok #")语句仅用于测试目的。

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

int main() {
    char password[20];
    int i, length;
    int numbers[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    char letters[] = { 'a', 'b', 'c', 'c', 'e', 'f', 'g', 'h',
                       'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
                       'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
                       'y', 'z' };
    char symbols[] = { '!', '@', '#', '$', '%', '^', '&', '*', 
                       '-', '_', '+', '=' };

    printf("Password rules:\n"
           " --------------------- \n"
           " must follow the format ee$L1LL$L$$eL \n"
           " --------------------- \n"
           " Please enter your current password:");
    scanf("%c", password);
    printf("%19s", password);

    length = strlen(password);

    if (length = 13) {
        printf("Password ok 1");
        for (int i = 0; i < strlen(letters); i++) {    
            if ((password[1] == letters[i]) && (password[2] == letters[i])) {
                printf("Password ok 2");
            } else {
                printf("Digits 1 or 2 do not fit the correct format");
            }
        }
        for (int i = 0; i < strlen(symbols); i++) {
            if (password[3] == symbols[i]) {
                printf("Password ok 3");
            } else {
                printf("Digit 3 does not fit the correct format");
            }
        }
        for (int i = 0; i < strlen(letters); i++) {
            if (password[4]==symbols[i]) {
                printf("Password ok 4");
            } else {
                printf("Digit 3 does not fit the correct format");
            }
        }
    } else if (length != 13) {
        printf("\nPassword must be 13 digits long");
    }
}
wfsdck30

wfsdck301#

如果你被允许使用ctype宏,比如isupper()islower(),那么你可以对每个模式字符调用它们。

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

enum { // Enumerate codes used in the password-pattern
    eLower = 'a',
    eUpper = 'B',
    eDigit = '1',
    eSymbol = '$'
};

char* pp_errors[] = { // Error strings for pattern-mismatch
    "No Error",
    "Lower case letter expected",
    "Upper case letter expected",
    "Digit is expected",
    "Punctuation expected",
    "Pattern Not handled"
};

int
check_pattern_char (const unsigned char pwdC, const unsigned char patC)
{
    switch (patC) {
    case eLower : if (!islower (pwdC)) return 1;
        break;
    case eUpper : if (!isupper (pwdC)) return 2;
        break;
    case eDigit : if (!isdigit (pwdC)) return 3;
        break;
    case eSymbol : if (!ispunct (pwdC)) return 4;
        break;
    default: return 5; // pattern not handled
    }
    return 0;
}

int main ()
{
    char password [128];
    char pattern [] = "aa$B1BB$B$$aB";
    int ptlen = strlen (pattern);

    printf ("Enter a password that follows pattern [%s]: ", pattern);
    while (1 != scanf ("%127s", password));
    if ( (int) strlen (password) != ptlen) {
        printf ("\nPassword must be [%d] chars long.\n", ptlen);
        return 1;
    }
    for (int pi = 0; pi < ptlen; ++pi) {
        int status;
        if ( (status = check_pattern_char (password[pi], pattern[pi]))) {
            printf ("\nERROR: [%s] at pos[%d] [%c][%c]\n",
                    pp_errors[status], pi + 1, pattern[pi], password[pi]);
            return 2;
        }
    }
    printf ("\nPassword [%s] accepted against Pattern[%s]\n", password, pattern);
    return 0;
}

或者你可以为它们编写自己的函数,比如:

static inline int my_islower (const char ch) {
    return (ch >= 'a' && ch <= 'z');
}
static inline int my_isupper (const char ch) {
    return (ch >= 'A' && ch <= 'Z');
}
static inline int my_isdigit (const char ch) {
    return (ch >= '0' && ch <= '9');
}
static inline int my_ispunct (const char ch) {
    // allowed punctuations
    char puncts[] = "!@#$%^&*-_+=";
    for (char* pp = puncts; *pp; )
        if (*pp++ == ch) return 1;
    return 0;
}

static inline告诉编译器这个函数是这个translation-unit(当前文件)的本地函数&如果可能的话,请求它在调用位置内联函数。这减轻了调用小函数的开销。

x7yiwoj4

x7yiwoj42#

检查密码是否符合

format aa$B1BB$B$$aB

使用fgets()读取,sscanf()扫描,"%n"检测扫描结束。

// scanf("%c",password); // %c only reads 1 character
// printf("%19s",password);

if (fgets(password, sizeof password, stdin)) {
  password[strcspn(password, "\n")] = '\0'; // Lop off potential \n
  printf("<%s>\n", password);
  int n = 0; 
  // format aa$B1BB$B$$aB
  #define FMT_a "%*1[a-z]"
  #define FMT_B "%*1[A-Z]"
  #define FMT_1 "%*1[0-9]"
  #define FMT_S "%*1[-!@#$%^&*_+=]"  // '-' first
  sscanf(password, 
      FMT_a FMT_a FMT_S FMT_B FMT_1 FMT_B FMT_B FMT_S FMT_B FMT_S FMT_S FMT_a FMT_B "%n",
      &n);
  bool Success = n > 0 && password[n] == '\0';

一种更健壮的方法是在字母[a-z]不连续的情况下使用一系列strchr()调用。
IMO,使用更慷慨的读取缓冲区。

// char password[20];
char password[100];
8fsztsew

8fsztsew3#

下面的代码是完美的使用ctype.h

#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdbool.h>

bool valid(const char *password);

int main(void)
{
    char password[] = "Password@123";
    if (valid(password))
    {
        printf("Your password is valid!\n");
    }
    else
    {
        printf("Your password needs at least one uppercase letter, lowercase letter, number and symbol\n");
    }
}

// TODO: Complete the Boolean function below
bool valid(const char *password)
{
    int length = strlen(password);
    int lower_count = 0;
    int upper_count = 0;
    int digit_count = 0;
    int symbol_count = 0;
    for(int i = 0; i < length; i++){
        if(islower(password[i])){
         lower_count += 1;
    }
        if(isupper(password[i])){
             upper_count += 1;
        }
        if(isdigit(password[i])){
             digit_count += 1;
        }
        if(ispunct(password[i])){
            symbol_count += 1;
        }
    }

printf("Lower Count: %d\nUpper Count: %d\nDigit Count: %d\nSymbol Count: %d\n", lower_count, upper_count, digit_count, symbol_count);
    if(lower_count != 0 && upper_count != 0 && digit_count != 0 && symbol_count != 0){
        return true;
    }
    return false;
}

输出为:

计数下限:7
上限计数:1
数字计数:3
符号计数:1
您的密码有效!

相关问题