LINUX.ORG.RU
Ответ на: комментарий от mystery

хотя бы 1 заглавную, 1 строчную и 1 цифру

тогда любого одного из этих условий достаточно? Я так понимаю, все три условия должны выполниться?

Harald ★★★★★
()
Ответ на: комментарий от mystery
if ( isdigit(a))
  z |= 1;

if (islower(a))
  z |= 2;

if (isupper(a))
  z |= 4;

...

if (z == 7) { printf("YES"); }

Harald ★★★★★
()
#include <stdio.h>
#include <ctype.h>

int
testpw(char *pw)
{
        int hasUpper = 0;
        int hasLower = 0;
        int hasDigit = 0;
        char *s;

        for (s = pw; *s; s++) {
                if (!isascii(*s))
                        return 0;
                if (isupper(*s))
                        hasUpper = 1;
                if (islower(*s))
                        hasLower = 1;
                if (isdigit(*s))
                        hasDigit = 1;
        }

        return hasUpper && hasLower && hasDigit && s-pw >= 6;
}

int
main(int argc, char **argv)
{
        if (argc > 1) {
                if (testpw(argv[1]))
                        puts("ok");
                else
                        puts("not ok");
        }

        return 0;
}
beastie ★★★★★
()
Последнее исправление: beastie (всего исправлений: 1)
Ответ на: комментарий от beastie

спасибо за помощь, но
implicit function declaration
так то я собираю с -Wno-implicit-function-declaration
Но все же, как обойти warning этот?

mystery ★★
() автор топика
Ответ на: комментарий от beastie

И все равно не работает
Пароли qwerty не должен пропускать, а пропускает

mystery ★★
() автор топика
Ответ на: комментарий от beastie

Вот только то, что нафигачили гнутые не исправить

mystery ★★
() автор топика
#include <stdio.h>
#include <ctype.h>

#define MINLENGTH 6
#define MAXLENGTH 18

enum validation { INVALID = 0, ISUPPER = 1, ISLOWER = 2, ISDIGIT = 4 };

int
main(void)
{
    char password[MAXLENGTH + 1];

    int index = 0;
    int next;
    enum validation valid = INVALID;

    while ((next = getchar()) != '\n' && index < MAXLENGTH) {
        if (isdigit(next)) {
            valid = valid | ISDIGIT;
        } else if (isupper(next)) {
            valid = valid | ISUPPER;
        } else if (islower(next)) {
            valid = valid | ISLOWER;
        }

        password[index++] = next;
    }
    password[index] = '\0';

    if (valid != (ISDIGIT | ISLOWER | ISUPPER) || index < MINLENGTH) {
        printf("Invalid, %s", password);
    } else {
        printf("Valid, %s", password);
    }

    return 0;
}

Я просто так вывожу пароль. Ты не парься. И да, массив 18+1 учитывая '\0' в конце.

Deleted
()
Последнее исправление: merhalak (всего исправлений: 2)
Ответ на: комментарий от Deleted

Всем, кто использует is* функции без isascii — так вот, проверка на isascii — обязательна.

Правильно будет:

if (isascii(next) && isdigit(next))
    /* ... */

beastie ★★★★★
()
Ответ на: комментарий от beastie

Буду знать, в олимпиадных не приходилось до сих пор использовать. Да и в K&R я не заметил isascii. Оно не в приложении Б?

Deleted
()

strspn from http://www.ioccc.org/1992/ant.c

#include<string.h>

int tst(const char *s){
        int len=strlen(s);
        return (strcspn(s,"0123456789")!=len)
               &&(strcspn(s,"abcdefghijklmnopqrstuvwxyz")!=len)
               &&(strcspn(s,"ABCDEFGHIJKLMNOPQRSTUVWXYZ")!=len)
}

можно короче.

qulinxao ★★☆
()
Ответ на: комментарий от KivApple

забавная оценка

В реальности Abcd1234 и Password1 — плохие пароли, а mu-icac-of-jaz-doad — хороший пароль. В этом несложно убедиться. [ссылка на сервис васи пупкина, специалиста по секьюрной секьюрности паролей]

newquestion
()
Ответ на: комментарий от beastie

Всем, кто использует is* функции без isascii — так вот, проверка на isascii — обязательна.

С чего это вдруг? Не обязательна, ты просто ограничиваешь пароль только ascii символами.

mashina ★★★★★
()
Ответ на: комментарий от TheAnonymous

Уже и не припомню, от куда я это знаю. Но is* могут быть и макросами (мы ведь пишем портабельный код?), а так же, что использование их с signed char (значения >= 0x7f) могут привести к весёлым результатам. Поэтому, это как минимум «хороший тон» перестраховаться и ограничиться нижней частью ascii таблицы. В верхней всё равно не digit, не upper, не lower быть не могут.

beastie ★★★★★
()
Последнее исправление: beastie (всего исправлений: 1)
Ответ на: комментарий от beastie

Ну дак, это типичная задача для веба. На слабой машине, на ff 10000 итераций проверки 10-значной строки выполняется за 5 миллисекунд, на v8 — за 4. Слишком медленно?

newquestion
()
Ответ на: комментарий от beastie

А у тебя несколько лишних if-ов, и бесполезная isascii снижающая throughput. Нужно стандартизировать входные данные, а потом впихивать перестраховки, если они нужны.

anonymous
()
Ответ на: комментарий от newquestion

Но между тем он прав.

Abcd1234 реально плохой пароль, а твоя программа его пропустит.

KivApple ★★★★★
()

(pwd[0]|pwd[1]|....) далее проверить старшие биты.

MKuznetsov ★★★★★
()
Ответ на: комментарий от beastie

is...() функции вызываются от int, по K&R

Deleted
()
Ответ на: комментарий от Deleted

не практически, а для любого. по крайней мере на олимпиадах, на которых был я.

f1u77y ★★★★
()
Ответ на: комментарий от mashina

Открыл:

CAVEATS
     The argument to isupper() must be EOF or representable as an unsigned
     char; otherwise, the result is undefined.
Ы?

beastie ★★★★★
()
Ответ на: комментарий от beastie

Если бы FSM, то это было бы молниеносно быстро. Там по-любому рекурсивный бэктрэкинг.

Нормальный FSA (с нормальной имплементацией) ничем от выше-написаных циклов с if-else-if по сути не отличается.

invy ★★★★★
()
Последнее исправление: invy (всего исправлений: 1)

Нужно, что бы он содержал хотя бы 1 заглавную, 1 строчную и 1 цифру

Не нужно.

Ибо это никак не связано с его криптостойкостью

buddhist ★★★★★
()
#include <ctype.h>
#include <err.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[])
{
    char    *pw;
    int      pw_len;
    bool     got_upper = false;
    bool     got_lower = false;
    bool     got_digit = false;
    bool     pw_ok = false;

    if (argc != 2)
        errx(EXIT_FAILURE, "one argument required");

    pw = argv[1];
    pw_len = strlen(argv[1]);

    if (pw_len < 6)
        errx(EXIT_FAILURE, "password is too short");

    if (pw_len > 18)
        errx(EXIT_FAILURE, "password is too long");

    for (int i = 0; i < pw_len; ++i) {
        if (!got_upper && isupper(pw[i]))
            got_upper = true;
        else if (!got_lower && islower(pw[i]))
            got_lower = true;
        else if (!got_digit && isdigit(pw[i]))
            got_digit = true;

        pw_ok = got_upper && got_lower && got_digit;

        if (pw_ok)
            break;
    }

    if (pw_ok)
        puts("pw is ok");
    else
        puts("pw is not ok");

    exit(EXIT_SUCCESS);
}
kirk_johnson ★☆
()
Ответ на: комментарий от TheAnonymous

Может, и не обязательна, но тогда нужно и массивы под строку делать «многобайтными», не?

al_exquemelin ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.