j1 docs
This commit is contained in:
57
j1-Passwoerter/README.md
Normal file
57
j1-Passwoerter/README.md
Normal file
@ -0,0 +1,57 @@
|
||||
# Allgemeine Informationen
|
||||
|
||||
Die Grundidee für meinen Passwortgenerator ist das Passwort aus richtigen Wörtern zu bilden.
|
||||
Als erstes Argument muss man einen Dateipfad zu der Textdatei mit einer Liste von Wörtern, die von einem Zeilenumbruch getrennt sind, verwenden.
|
||||
Unter wörter.txt ist ein Beispiel dafür ([Quelle](https://www.netzmafia.de/software/wordlists/deutsch.txt)).
|
||||
Das Passwort wird zu stdout ausgegeben.
|
||||
|
||||
# Regeln für das generierte Passwort
|
||||
|
||||
1. Zufällige Wörter werden aus der Wörterliste ausgewählt.
|
||||
2. Am Anfang des Passworts und zwischen den Wörtern steht eine Ziffer.
|
||||
3. Am Ende steht ein Satzzeichen.
|
||||
|
||||
# Funktionsweise
|
||||
|
||||
Als erstes wird die angebene Textdatei mit der Wörterliste ausgelesen.
|
||||
Alle Zeilenumbrüche werden durch \0 ersetzt und Pointer zu jedem Wort in einem Array gespeichert.
|
||||
```
|
||||
for(char *i = woerterText; (uintptr_t)i < dest; ++i) {
|
||||
if(*i == '\n') {
|
||||
char *nextWord = i + 1;
|
||||
woerter = acl_arraylist_append(woerter, &nextWord);
|
||||
pointerCheck(woerter);
|
||||
*i = '\0';
|
||||
}
|
||||
}
|
||||
```
|
||||
Danach werden Bytes mit zufälligen Werten von `/dev/random` ausgelesen.<br>
|
||||
` fread(randomInt, sizeof *randomInt, randomInt_len, randomFile);`<br>
|
||||
Dafür habe ich mich entschieden, da dieser ein krypografisch sicherer Zufallszahlengenerator ist.
|
||||
Passwörter, die mit Pseudozufallszahlengeneratoren generiert werden, sind einfach zu knacken, da bei diesen jede Zufallszahl von der vorherigen abhängt.
|
||||
Oft wird als Startwert auch noch die aktuelle Zeit benutzt, was das Ganze noch unsicherer macht.
|
||||
Auf Basis der Zufahlszahlen wird dann das Passwort aus Wörtern und Ziffern zusammengesetzt.
|
||||
```
|
||||
for(uint32_t i = wordsForPass_len; i < randomInt_len; ++i, ++j) {
|
||||
char buf[2];
|
||||
buf[1] = '\0';
|
||||
sprintf(buf, "%" PRIu32, randomInt[i] % 10);
|
||||
strcat(password, buf);
|
||||
strcat(password, wordsForPass[j]);
|
||||
}
|
||||
```
|
||||
Zum Schluss wird noch ein zufälliges Satzzeichen angehängt.
|
||||
```
|
||||
const char specialCharacter[] = {'?', '.', ',', '!', ';'};
|
||||
char randomSpecialCharacter[] = {specialCharacter[randomInt[randomInt_len - 1]
|
||||
% (sizeof specialCharacter - 1)], '\0'};
|
||||
```
|
||||
Dann wird das Passwort wird schließlich ausgegeben.
|
||||
|
||||
# Beispiel
|
||||
|
||||
Beipielausgabe: `0zaehneknirschend8verraeterischem6veranstaltet,`<br>
|
||||
Die Textdatei in diesem Fall wörter.txt wurde ausgelesen, \\n durch \0 ersetzt um das Ende vom String zu markieren.
|
||||
Danach wurden Pointer zu jedem Wort der Textdatei erstellt.
|
||||
Anschließend wurden die Wörter zaehneknischend, verraeterischem, veranstaltet, die Ziffern 0, 8, 6 ausgewählt und zusammengesetzt.
|
||||
Ein Komma wurde angehängt und das Passwort schließlich ausgegeben.
|
||||
Binary file not shown.
@ -1,13 +1,3 @@
|
||||
/* Die Grundidee für meinen Passwortgenrator ist richtigen Wörtern zu bilden.
|
||||
* Als erstes Argument muss man den Programm einen Dateipfad zu der Textdatei mit Liste von Wörtern, die mit \n getrennt sind.
|
||||
* Unter wörter.txt ist ein Beispiel dafür. Quelle: https://www.netzmafia.de/software/wordlists/deutsch.txt
|
||||
* Das Passwort wird zu stdout ausgegeben.
|
||||
*
|
||||
* Regeln für das generierte Passwort:
|
||||
* 1. zufäfflige Wörter werden aus der Wörterliste ausgewählt.
|
||||
* 2. Am Anfang des Passworts und zwischen den Wörtern steht eine Ziffer.
|
||||
* 3. Am Ende steht ein Satzzeichen.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <acl/file.h>
|
||||
#include <string.h>
|
||||
@ -19,7 +9,7 @@
|
||||
#define wordCount 3 // Anzahl der Wörter des Passworts
|
||||
#define randomInt_len (2 * wordCount)
|
||||
#define wordsForPass_len randomInt_len / 2
|
||||
void pointerCheck(void *pointer) {
|
||||
void pointerCheck(void *pointer) { // Funktion um auf NULL Pointer zu checken und den Fehler auszugeben.
|
||||
if(pointer == NULL) {
|
||||
perror("Error: ");
|
||||
exit(-1);
|
||||
@ -27,33 +17,45 @@ void pointerCheck(void *pointer) {
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if(argc != 2) printf("file argument required");
|
||||
if(argc != 2) {
|
||||
printf("file argument required"); // checkt ob der Nutzer die richtige Anzahl von Argumenten verwendet hat.
|
||||
exit(-1);
|
||||
}
|
||||
bool sucess;
|
||||
FILE *fp = fopen(argv[1], "rb"); // im binären Modus zu lesen ist deutlich schneller als im Textmodus, da man dort jede Zeile einzeln lesen muss. So wurde aus mehreren Sekunden Wartezeit keine bemerkbare Verzögerung.
|
||||
|
||||
/* im binären Modus zu lesen ist deutlich schneller als im Textmodus, da man dort jede Zeile einzeln lesen muss.
|
||||
* So wurde aus mehreren Sekunden Wartezeit eine nicht bemerkbare Verzögerung. */
|
||||
FILE *fp = fopen(argv[1], "rb");
|
||||
char *woerterText = acl_ReadTextFile(fp, &sucess);
|
||||
if(!sucess) perror("Error: ");
|
||||
fclose(fp);
|
||||
unsigned len = strlen(woerterText);
|
||||
uintptr_t dest = (uintptr_t)woerterText + len;
|
||||
char **woerter = acl_arraylist_create(1, sizeof *woerter);
|
||||
|
||||
/* erstellt ein Array für die Pointer zu den Wörtern.
|
||||
* Man könnte auch erst die Zeilenumbrüche zählen, um den Arbeitsspeicher auf einmal anzufragen.
|
||||
* Dies würde das Programm vermutlich etwas schneller machen.
|
||||
* Jedoch ist das Programm so einfacher zu verstehen und im Vergleich zum Auslesen der Textdatei wäre die Geschwindigkeitsverbesserung sehr gering. */
|
||||
char **woerter = acl_arraylist_create(1, sizeof *woerter);
|
||||
pointerCheck(woerter);
|
||||
woerter[0] = woerterText;
|
||||
for(char *i = woerterText; (uintptr_t)i < dest; ++i) {
|
||||
if(*i == '\n') {
|
||||
char *nextWord = i + 1;
|
||||
woerter = acl_arraylist_append(woerter, &nextWord); // Pointer werden zu Begin jedes Wortes erstellt.
|
||||
woerter = acl_arraylist_append(woerter, &nextWord); // Pointer werden am Anfang jedes Wortes erstellt.
|
||||
pointerCheck(woerter);
|
||||
*i = '\0'; // \n wird mit \0 ersetzt um das Ende des Strings markieren.
|
||||
*i = '\0'; // \n wird durch \0 ersetzt um das Ende des Strings markieren.
|
||||
// diesen Weg habe ich gewählt um viele memory allocations zu vermeiden.
|
||||
}
|
||||
}
|
||||
FILE *randomFile = fopen("/dev/random", "rb");
|
||||
FILE *randomFile = fopen("/dev/random", "rb"); // /dev/random ist ein kryptografisch sicherer Zufallszahlengenerator.
|
||||
uint32_t randomInt[randomInt_len];
|
||||
fread(randomInt, sizeof *randomInt, randomInt_len, randomFile);
|
||||
size_t passLen = wordsForPass_len + 1; // weil Ziffern im Passwort gleich oft vorkommen wie Wörter. + 1 für ein Satzzeichen am Ende
|
||||
char *wordsForPass[wordsForPass_len];
|
||||
// Die Länge des Passwortes wird berechnet.
|
||||
for(uint32_t i = 0; i < wordsForPass_len; ++i) {
|
||||
wordsForPass[i] = woerter[randomInt[i] % acl_arraylist_len(woerter)]; // der modulo operator wird verwendet um die Zahlfallszahl auf den gewünschten Zahlenbereich zu reduzieren.
|
||||
wordsForPass[i] = woerter[randomInt[i] % acl_arraylist_len(woerter)]; // der modulo Operator wird verwendet um die Zufallszahl auf den gewünschten Zahlenbereich zu reduzieren.
|
||||
passLen += strlen(wordsForPass[i]);
|
||||
}
|
||||
char *password = malloc(passLen + 1);
|
||||
@ -66,7 +68,9 @@ int main(int argc, char *argv[]) {
|
||||
strcat(password, buf);
|
||||
strcat(password, wordsForPass[j]);
|
||||
}
|
||||
free(woerterText);
|
||||
// ein zufälliges Sonderzeichen wird angehängt.
|
||||
const char specialCharacter[] = {'?', '.', ',', '!', ';'};
|
||||
char randomSpecialCharacter[] = {specialCharacter[randomInt[randomInt_len - 1] % (sizeof specialCharacter - 1)], '\0'};
|
||||
printf("%s", strcat(password, randomSpecialCharacter));
|
||||
printf("%s\n", strcat(password, randomSpecialCharacter));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user