Click here to Skip to main content
15,392,679 members
Please Sign up or sign in to vote.
1.00/5 (3 votes)
See more:
I need to make a C program that will take the password database from the file and check the password, and then it will display statistics. In the course of writing the program, I stopped at the moment when I needed to check the password according to certain criteria, and for 4 days I could not think of anything and fix it. Now I will attach a translation of my technical specification:
______________________________________________________________________________________

1. Startup parameters $ gcc -std = c99 -Wall -Wextra -Werror pwcheck.c -o pwchec
2. ./pwcheck LEVEL PARAMETERS [--stats]
--stats, if specified, controls whether summary statistics of parsed passwords should be displayed at the end of the program

LEVEL - an integer in the range [1, 4] indicating the required security level (see below)

PARAMETERS - is a positive integer indicating
additional rule parameter (see below)

3. Security levels (controlled rules)

List of rules:

lvl1 Password must contain at least 1 uppercase and 1 lowercase letter.
lvl2 The password contains characters from at least X groups (if the number X is greater than 4, this means all groups).
The following groups are considered:
1) lowercase letters (az)
2) uppercase letters (AZ)
3) numbers (0-9)
4) special characters (at least non-alphanumeric characters from the ASCII table in positions 33-126 32-126 should be supported, i.e. including space)
lvl3 Password does not contain the same sequence of characters at least X.
lvl4 Password does not contain two identical substrings at least X.

4. Statistics

If the specified program argument is --stats, the program should print general statistics at the end of the output in the format:
Statistics:
Various characters: NCHARS
Minimum length: MIN
Average length: AVG

NCHARS is the number of different characters found in all passwords
MIN is the length of the shortest password (or passwords)
AVG is the average password length (arithmetic mean), rounded to 1 decimal place

///// The statistics also include passwords that have been discarded.


5. Implementation details

1) Input data (list of passwords)
The list of passwords is passed to the program on standard input (stdin). Each password is entered on a separate line and contains only ASCII text data, excluding the newline character. The maximum password length is 100 characters, otherwise it is invalid data. The program must support an unlimited number of passwords at the entrance.
2) Program output
The standard output program (stdout) prints passwords from the input list, each on a separate line, that correspond to the required security level specified as an argument to the LEVEL program. Passwords should be listed unchanged and in the same order in which they were listed in the entry.

///// After displaying the list of passwords, the program additionally displays statistics (see Statistics).
6. Limitations in the project
The following functions are prohibited:

-calling functions from the string.h and ctype.h libraries - the goal of the project is to learn how to implement these functions manually,
-calls from the families malloc and free - working with dynamic memory is not needed in this project,
-calls from the fopen, fclose, fscanf, ... family - work with files is undesirable in this project (temporary),
-Calling the exit function - the goal of the project is to learn how to create program constructs that can handle an unexpected state of the program and, possibly, terminate the program correctly by returning from the main function.
____________________________________________________________________________________

I have been learning C for only a few weeks and I have already been asked to write this((((( I have attached my code, but it is still raw and not working, if you could correct at least this, I would be very grateful

What I have tried:

C
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#define CAPITAL (line[i]>='A' && line[i]<='Z')
#define SMALL (line[i]>='a' && line[i]<='z')
#define SPECIAL ((line[i]>=32&&line[i]<=47)||(line[i]>=58&&line[i]<=64)||(line[i]>=91&&line[i]<=96)||(line[i]>=123&&line[i]<=126))
int main(void) {
int i = 0, total = 0, capital=0 , small=0 ,  special=0;
    char line[100][100];
    FILE *plist = NULL;
plist = fopen("1te.txt", "r");
    while(fgets(line[i], 80 , plist)) {
        i++;}
total = i;
for(i = 0; i < total; ++i)
{
 if((line[i]>='A' && line[i]<='Z'))
  small=1;
 if((line[i]>='a' && line[i]<='z'))
  capital=1;
 if(((line[i]>=32&&line[i]<=47)||(line[i]>=58&&line[i]<=64)||(line[i]>=91&&line[i]<=96)||(line[i]>=123&&line[i]<=126)))
  special=1;
}
if(capital==0 || small==0 || special==0) printf("\n\tInvalid Password");
else
printf("\n\tValid Password");
getch();
return 0;
}
Posted
Updated 29-Oct-21 9:36am
v2
Comments
Richard MacCutchan 29-Oct-21 10:26am
   
What is the problem? You say you get an error but you do not explain what error.
Денис Гуреля 29-Oct-21 10:40am
   
This is an error in the code : ISO C++ forbids comparison between pointer and integer [-fpermissive]
Separately, the file with reading the file and outputting the array through printf works, the part with checks works on passwords entered through scanf, but these two parts together do not want to work
Richard MacCutchan 29-Oct-21 10:50am
   
You seem to be starting from the wrong point here. If you read your instructions there are a number of parameters that can be passed in to the program, but you are not even allowing for them. You have declared three macros (CAPITAL, SMALL and SPECIAL) although none will work. But you also ignore them and write inline tests, which you misuse by setting small if the letter is a capital, and vice versa. and you do not check for digits as listed in your instructions. So, as OriginalGriff suggests below you should throw this code away and start afress, by reading your instructions and following them one step at a time.

First off, sort out your indentation: nothing makes it more obvious that you copy'n'pasted code than having different indentation styles and depths.

Then, when you copy and paste code it's not going to work as is: the code you found to check password validity is
a) Poorly written
b) Expecting to check a single string, not an array of strings.

So ... move that code to a separate function, pass it each line at a time, and use a struct to pass the password stats into and out of the function.

And if you have any sense, write your own function to do the validation instead of relying on poor student grade code you can find to do your homework for you ...
   
I would add to what Mr. Griff wrote by stating that in my opinion you should use character values instead of numbers in your comparison - the third if condition in your for loop. Here is how that could look :
C++
for(i = 0; i < total; ++i)
{
    int length = strlen( line[ i ];
    for( int n = 0; n < length; ++n )
    {
        char chr = line[ i ][ n ];
        if( chr >= 'A' && chr <= 'Z' )
            capital = 1;
        else if( chr >= 'a' && chr <= 'z' )
            small = 1;
        else if( chr >= ' ' && chr <= '/' )
            special = 1;
        else if( chr >= ':' && chr <= '@' )
            special = 1;
        else if( chr >= '[' && chr <= '\'' )
            special = 1;
        else if( chr >= '{' && chr <= '~' )
            special = 1;
    }
}
also, the subsequent ifs be can else ifs so the condition is not checked repeatedly.
   
v2
Comments
Richard MacCutchan 30-Oct-21 4:08am
   
Except that line[i] is an array, not a single character. Also the code gets capital and small the wrong way round.
Rick York 30-Oct-21 15:04pm
   
That you for the corrections.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900