Zufälliger String aus Buchstaben und Zahlen

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
fabske
Beiträge: 2023
Registriert: 14.06.2003 15:07:51

Zufälliger String aus Buchstaben und Zahlen

Beitrag von fabske » 23.12.2006 00:19:32

Ich bin gerade am Schreiben eines Shellskriptes und suche nun nach einer Möglichkeit zufällige 20-stellige Strings aus Buchstaben (ohne Umlaute) und Zahlen zu erstellen. Ich denke da an /dev/urandom, aber es gibt mir wirres Zeugs aus. Wer kann helfen?
Danke
Bevor Du einen Beitrag postest:
- Kennst Du unsere Verhaltensregeln?
- Hast Du die Suchfunktion benutzt? Deine Frage wurde vielleicht schon in einem anderen Beitrag beantwortet.
- Ist schon ein Artikel in unserem Wiki vorhanden, der Deine Frage beantwortet?

cosmac
Beiträge: 4576
Registriert: 28.03.2005 22:24:30

Beitrag von cosmac » 23.12.2006 00:32:54

moin, moin,

Code: Alles auswählen

ZUFALLSTEXT=`makepasswd --chars=20`
macht ziemlich genau das. Vielleicht kommt auch "uuidgen" in Frage.
Beware of programmers who carry screwdrivers.

Benutzeravatar
H4kk3r
Beiträge: 724
Registriert: 02.01.2006 16:50:51
Wohnort: in der Nähe von Heidelberg

Beitrag von H4kk3r » 23.12.2006 00:51:59

Code: Alles auswählen

pwgen
Die Man-Page liefert ein paar interessante Infos.
Gruß, Marcus

„Well done! We did it!“

Debian testing
kernel 2.6.18.3
IBM R50e UR0S5GE

Benutzeravatar
fabske
Beiträge: 2023
Registriert: 14.06.2003 15:07:51

Beitrag von fabske » 23.12.2006 13:44:02

Aber diese Prozesse sind doch sehr performancelastig? Das Problem ist, dieses Shellskript wird ca 50000 mal pro Mintue aufgerufen werden und sollte dementsprechend sehr sehr effizient sein. Der Zufall muss auch nicht so gut sein!
Bevor Du einen Beitrag postest:
- Kennst Du unsere Verhaltensregeln?
- Hast Du die Suchfunktion benutzt? Deine Frage wurde vielleicht schon in einem anderen Beitrag beantwortet.
- Ist schon ein Artikel in unserem Wiki vorhanden, der Deine Frage beantwortet?

cosmac
Beiträge: 4576
Registriert: 28.03.2005 22:24:30

Beitrag von cosmac » 23.12.2006 14:29:05

"makepasswd" benutzt per default nur einen Startwert aus /dev/random
und erzeugt dann mit einem eigenen Pseudo-Random-Generator beliebig
viele Worte (--count=N). Wenn du das ausnutzen kannst, ist es nicht sooo
langsam:

Code: Alles auswählen

$ cat /proc/cpuinfo
AMD Athlon(tm) XP 1800+
$ time makepasswd --chars=20 --count=50000 > /tmp/liste1
real    0m4.677s
user    0m4.575s
sys     0m0.013s
Das schaut auch nicht schlecht aus:

Code: Alles auswählen

time openssl rand -base64 1000000 > /tmp/liste2
real    0m0.107s
user    0m0.101s
sys     0m0.006s
Aber ich schätz mal, daß ein Shell-Script für 50000/Min sowieso zu langsam
wird. Und in einem C-Programm kannst du einfach random() benutzen.
Beware of programmers who carry screwdrivers.

Benutzeravatar
napo
Beiträge: 230
Registriert: 27.07.2004 15:07:54

Beitrag von napo » 23.12.2006 14:58:50

Und ich schätze, dass 50000 mal in der Minute dein Rechner nicht schaffen wird.

Ich hab mal folgendes C-Programm geschrieben, also test.c

Code: Alles auswählen

int main() {
        return 0;
}
Und folgendes Skript ruft dieses Test-Programm 50000 mal auf

Code: Alles auswählen

#!/bin/sh
for ((c=0;c<50000;c++))
do
./test
done
Und time ./test.sh liefert das hier:

Code: Alles auswählen

real    0m23.245s
user    0m7.392s
sys     0m14.459s
PS: Ich hab übrigens ein Pentium-M mit 1,6 GHz

Benutzeravatar
fabske
Beiträge: 2023
Registriert: 14.06.2003 15:07:51

Beitrag von fabske » 23.12.2006 15:45:31

Also was ratet ihr mir? Soll ich ein C Programm nehmen?
Das ganze sieht so aus. Ich brauche auf dem Rechner ein Programm, welches 50000/Minute von einem PHP Skript aufgerufen wird. Dieses Programm erzeugt einen Zufallsstring, macht etwas mit dem, und gibt ihn an das aufrufende PHP Skript zurück.
Rückgabewerte können in Shellskripte ja nur Zahlen sein. Haltet ihr es für besser ein kleines Shellskript oder ein C Programm zu schreiben?
Wäre es besser das Programm jedesmal aufzurufen oder eines ständig laufen zu lassen, dem man laufend Parameter übergibt?
Bevor Du einen Beitrag postest:
- Kennst Du unsere Verhaltensregeln?
- Hast Du die Suchfunktion benutzt? Deine Frage wurde vielleicht schon in einem anderen Beitrag beantwortet.
- Ist schon ein Artikel in unserem Wiki vorhanden, der Deine Frage beantwortet?

cosmac
Beiträge: 4576
Registriert: 28.03.2005 22:24:30

Beitrag von cosmac » 23.12.2006 16:53:22

kannst du das nicht gleich in dem PHP-Script machen? Grundsätzlich solltest
du drauf achten, möglichst wenig neue Prozesse pro Durchlauf zu erzeugen,
also möglichst kein Programm aufrufen (und schon garkein Script).

Oder könnte ein C-Programm das komplette PHP-Script ersetzen? Z.B. geht
CGI mit C genauso einfach wie mit PHP. Das brächte echt Geschwindigkeit.
Beware of programmers who carry screwdrivers.

Benutzeravatar
fabske
Beiträge: 2023
Registriert: 14.06.2003 15:07:51

Beitrag von fabske » 23.12.2006 17:37:22

Nein, ich kann es nicht mit PHP machen, das muss getrennt sein!
Warum möglichst wenig Prozesse aufrufen?
Da ich ja nur Zahlen als Wert von exit aus meinem Skript an das PHP zurückgeben kann, sollte ich nun auch anstatt einen Zufallsstring eine Zufallszahl der Länge 20 haben, aber wie?
Bevor Du einen Beitrag postest:
- Kennst Du unsere Verhaltensregeln?
- Hast Du die Suchfunktion benutzt? Deine Frage wurde vielleicht schon in einem anderen Beitrag beantwortet.
- Ist schon ein Artikel in unserem Wiki vorhanden, der Deine Frage beantwortet?

Benutzeravatar
armin
Beiträge: 2682
Registriert: 17.03.2005 11:49:14

Beitrag von armin » 23.12.2006 17:48:55

mohameth hat geschrieben:Warum möglichst wenig Prozesse aufrufen?
Da das Erzeugen von Prozessen sehr teuer ist.
Formerly known as Trigger.
HP 8510p - Debian Sid
Mitglied des Debian-KDE-Teams

Benutzeravatar
fabske
Beiträge: 2023
Registriert: 14.06.2003 15:07:51

Beitrag von fabske » 23.12.2006 19:03:12

Also wäre es günstig wenn ich ein C Programm ständig laufen lassen würde? Dann muss ich aber eine Schnittstelle definieren, über die das PHP Skript dem C Programm einen Wert übergeben kann, und dann das C Programm dem PHP Skript wieder zurück. Wie macht man sowas? Stichwort?
Danke
Bevor Du einen Beitrag postest:
- Kennst Du unsere Verhaltensregeln?
- Hast Du die Suchfunktion benutzt? Deine Frage wurde vielleicht schon in einem anderen Beitrag beantwortet.
- Ist schon ein Artikel in unserem Wiki vorhanden, der Deine Frage beantwortet?

cosmac
Beiträge: 4576
Registriert: 28.03.2005 22:24:30

Beitrag von cosmac » 23.12.2006 21:13:05

Erstmal was zum exit-Rückgabewert: der ist eine Zahl mit 32 oder 64 Bit, je nach
System. Aber auch 64 Bit sind keine 20 Zeichen, maximal 16 wenn man nur Hex
erlaubt, ca. 10 wenn man Ziffern und Gross- und Kleinbuchstaben braucht.
Ein Programm oder Script kann aber auch über seine Standardausgabe beliebig
viel Text zurückgeben.

Dann zum Stichwort:
- Socket
- named Pipe, FIFO
- oder ein eigener Webserver -- verrückt, aber die schnellste Lösung, wenn man
sowas noch nie programmiert hat. Der ist auch nicht langsamer, aber von PHP
aus besonders einfach anzusprechen. Als Grundlage könnte der Quelltext von
"bozohttpd" dienen, der ist schön übersichtlich.
Beware of programmers who carry screwdrivers.

Benutzeravatar
fabske
Beiträge: 2023
Registriert: 14.06.2003 15:07:51

Beitrag von fabske » 23.12.2006 21:42:32

Das heißt, wenn ich mein Shellskript von einem PHP Skript aus aufrufe und dann irgendwo im Skript mal "Helo" auf die Standartausgabe schreibe, bekommt das aufrufende PHP Skript dieses "Helo"?
Wie schreibe ich in einem Shellskript auf die Standartausgabe?
Bevor Du einen Beitrag postest:
- Kennst Du unsere Verhaltensregeln?
- Hast Du die Suchfunktion benutzt? Deine Frage wurde vielleicht schon in einem anderen Beitrag beantwortet.
- Ist schon ein Artikel in unserem Wiki vorhanden, der Deine Frage beantwortet?

nepos
Beiträge: 5238
Registriert: 05.01.2005 10:08:12

Beitrag von nepos » 24.12.2006 01:47:33

Du schreibst mit echo auf die Standardausgabe. Und du musst es halt in PHP richtig aufrufen, so dass du die Ausgaben des Skripts bekommst.
Aber wieso bitte muss das Erzeugen dieser Zufallsfolge 500000 mal pro Minute passieren?

[matzi]
Beiträge: 16
Registriert: 20.05.2005 11:25:26
Wohnort: Weinheim
Kontaktdaten:

Beitrag von [matzi] » 24.12.2006 07:32:56

Moin mohameth,

um die Geschwindigkeit zu erhöhen könntest du ein programm schreiben, daß kontinuierlich Passwörten in eine named pipe schreibt. Das php script könnte diese pipe dann zum lesen öffnen und auslesen. Bei dieser Vorgehensweise werden keine neuen Prozesse gestartet.

Gruß
[matzi]

[matzi]
Beiträge: 16
Registriert: 20.05.2005 11:25:26
Wohnort: Weinheim
Kontaktdaten:

Beitrag von [matzi] » 24.12.2006 08:56:02

So ich hab' gerade mal ein kleines Programm geschrieben, daß etwa 1.000.000 Passwörter in der Minute erzeugt (P4 3.06 GHz). Die Frage ist nur ob dein php script mit dem einlesen mitkommt.

So geht's:

Code: Alles auswählen

$ gcc -O3 -o mohameths-passwort-generator mohameths-passwort-generator.c
$ mknod /tmp/mohameths-passwort-generator.pipe p
$ ./mohameths-passwort-generator 20 &
$ cat /tmp/mohameths-passwort-generator.pipe

Code: Alles auswählen

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

#define FIFO    "/tmp/mohameths-passwort-generator.pipe"
#define DEVRAND "/dev/urandom"
#define CHARS   "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"

int main(int argc, char *argv[])
{
    int fdr, fdp, i, l;
    ssize_t c;
    char *buf, *chars;

    chars = CHARS;
    l = atoi(argv[1]);
    buf = malloc(l);
    fdp = open(FIFO, O_RDWR);
    fdr = open(DEVRAND, O_RDONLY);
    while (1) {
        c = read(fdr, buf, l);
        for (i = 0; i < l; i++) {
            int r;

            r = *(buf + i) % strlen(chars);
            write(fdp, &chars[r], 1);
        }
        write(fdp, "\n", 1);
    }
    return 0;
}

Benutzeravatar
fabske
Beiträge: 2023
Registriert: 14.06.2003 15:07:51

Beitrag von fabske » 24.12.2006 11:51:56

:-D [matzi] vielen Dank, aber leider hast du mich nicht richtig verstanden.
Der Ablauf ist folgender. Das PHP Skript gibt einen Wert an das Programm. Das Programm macht etwas mit diesem Wert, in Verbindung mit einem Zufallsstring. Dann wird dieser Zufallsstring wieder an das PHP Skript zurück gegeben.
Das Programm ist eigentlich sehr klein und macht etwas auf Betriebssystemebene, wozu PHP zu langsam wäre und zu unsicher.
Ich bin gerade am Überlegen, ob ich dazu vielleicht Servlet benutzen soll ...
Bevor Du einen Beitrag postest:
- Kennst Du unsere Verhaltensregeln?
- Hast Du die Suchfunktion benutzt? Deine Frage wurde vielleicht schon in einem anderen Beitrag beantwortet.
- Ist schon ein Artikel in unserem Wiki vorhanden, der Deine Frage beantwortet?

Hajoe
Beiträge: 82
Registriert: 28.03.2006 10:07:07

Beitrag von Hajoe » 25.12.2006 11:37:33

Mach's doch einfach so:
1. Matrix mit festen Integerwerten
2. Systemzeit alle XX Durchläufe holen und in Integer umwandeln.
3. Bei jedem Durchlauf: Systemzeit mit einem anderen Wert aus der Matrix (inkrementeller Index) addieren oder multiplizieren (Integer - Overflow berücksichtigen). Das Ganze mit Deinem anderen Wert vernudeln. Die gewünschte Beschränkung auf Ziffern und/ oder Buchstaben erreicht man mit Modulo. Also z.B. 1234567 Modulo 128 ergibt den Ascii - Zeichensatz, die Bechränkung auf Ziffern sieht beispielsweise so aus: 1234567 Modulo 10 + 48. Die Systemzeit immer zu holen bringt nix, da der dahinterliegende Timer sowieso eine zu geringe Auflösung hat. Den optimalen Wert für XX muss man experimentell ermitteln. Das Ganze sollte sauschnell sein (ich hoffe verstanden worden zu sein).

Antworten