Προς το περιεχόμενο

Key genarator


NiKoS WSN

Προτεινόμενες αναρτήσεις

Δημοσ.

Αυτό το πρόγραμμα σε PHP δίνει τυχαία νούμερα δεκαεξαδικής μορφής αλλά δεν ξέρω αν είναι και μοναδικά. Για να είναι 10ψήφια τα νούμερα επεξεργάζεσαι την έξοδο της συνάρτησης.

 

>
<?php
function keygen($length=10)
{
$key = '';
list($usec, $sec)το = explode(' ', microtime());
mt_srand((float) $sec + ((float) $usec * 100000));

  	$inputs = array_merge(range('F','A'),range(0,9),range('A','F'));

  	for($i=0; $i<$length; $i++)
{
  	    $key .= $inputs{mt_rand(0,61)};
}
return $key;
}

echo keygen(40)."<br />";  // your results will vary
?>

Δημοσ.

 

 

βλεπω σ'αρεσε το ""[] tongue.gif

 

 

 

 

Χεχε, μέσω macros το χρησιμοποιώ συχνά έτσι κι αλλιώς, αλλά δεν έτυχε ποτέ να το κάνω απευθείας, π.χ. "abcd"[2] == 'b' οπότε σκάλωσα όταν μου το έδειξες έτσι γραμμένο :)

 

Δημοσ.

Αυτός που έγραψε το περίφημο "της νύχτας τα καμώματα τα βλέπει η μέρα και γελά" ήταν πολύ σοφός!

 

Έτσι μου 'ρχεται να τον σβήσω τελείως τον κώδικα που έγραψα χτες το βράδυ, μπας και περισώσω καμιά... ρανίδα αξιοπρέπειας, αλλά οκ, το αφήνω ως... αντιπαράδειγμα :lol:

 

Παρόλο που συνεχίζει να είναι αργός αλγοριθμικά στον έλεγχο μοναδικότητας του κάθε κλειδιού (δεν υπάρχει περίπτωση να κάτσω να γράψω rb-tree κώδικα για αυτό το πρόγραμμα :P) εν τούτοις σουλούπωσα αρκετά διάφορα άλλα πράματα.

 

Το βασικότερο είναι πως πλέον η παραμετροποίηση των επιλογών γίνεται με απλή προσθαφαίρεση γραμμών στον ορισμό μιας και μόνης μεταβλητής στην main(), της: options, που είναι ένα απλό bit-flagged byte. Οπότε μπορεί κανείς πολύ εύκολα πλέον να επιλέξει ποιες από τις ομάδες χαρακτήρων θα συμμετέχουν στην διαδικασία παραγωγής των κλειδιών, και να προσθαφαιρέσει απαιτήσεις ύπαρξης τουλάχιστον ενός χαρακτήρα από οποιαδήποτε ομάδα. Μπορεί ακόμα να επιλέξει ναι μεν να μην συμμετέχει γενικώς μια ομάδα χαρακτήρων στην παραγωγή, αλλά να υπάρχει εγγυημένα ένας τυχαίος χαρακτήρας της σε μια τυχαία θέση του κάθε κλειδιού.

 

Η παραμετροποίηση όμως του μεγέθους και του πλήθους των παραγόμενων κλειδιών εξακολουθεί να γίνεται με επεξεργασία των αντίστοιχων macros (όπως και τυχόν προσθαφαίρεση χαρακτήρων στις υπό-ομάδες χαρακτήρων).

 

Επίσης αφαίρεσα εκείνη την... ηλίθια απαίτηση που έκανα στην apply_demanded() για επιλογή αχρησιμοποίητου χαρακτήρα από τις υπο-ομάδες (ενώ αρκεί απαίτηση μονάχα για αχρησιμοποίητη θέση μέσα στο κλειδί).

 

Σε περίπτωση που θέλετε να αποθηκεύσετε την λίστα των παραγόμενων κλειδιών π.χ. σε ένα αρχείο keys.txt, απλά τρέξτε το πρόγραμμα σε γραμμή εντολών προσθέτοντας στο τέλος του ονόματός του " >keys.txt" (χωρίς τα εισαγωγικά). Το αρχείο που θα δημιουργηθεί θα έχει ένα κλειδί σε κάθε γραμμή.

 

>
/* ==========================================================================
* Program	:	keygen
* Author	:	migf1
* Language	:	C (C99)
* Description	:	a simple, slow & and rather unsafe generator of unique keys
* Source files	:	keygen.c
* gcc options	:	-std=c99
* CmdLn Usage	:	keygen [ >fname.txt ]
*
* Extra Notes	:
*
* In the source code, you may easily...
*	- change the size and the total count of the generated keys
*	- exclude/include any of the available char-sets from the key generation process
*	- add/remove chars to any of the available char-sets 
*	- demand at least 1 char from any of the available char-sets to be present
*	  in every generated key (even if the char-set is generally excluded )
* 
* ==========================================================================
*/

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <time.h>

#define KEYSIZE			10+1			// μέγεθος κλειδιού
#define NKEYS			15			// πλήθος κλειδιών

// Bitflag Options for the program (do not touch them, unless you are a programmer)
#define DEMAND_LOWER		(1 << 0)		// 0x01
#define DEMAND_UPPER		(1 << 1)		// 0x02
#define DEMAND_DIGITS		(1 << 2)		// 0x04
#define DEMAND_SPECL		(1 << 3)		// 0x08
#define USE_LOWER		(1 << 4)		// 0x10
#define USE_UPPER		(1 << 5)		// 0x20
#define USE_DIGITS		(1 << 6)		// 0x40
#define USE_SPECL		(1 << 7)		// 0x80

// Available Char-Sets (you may freely add or remove chars in any of those sets)
#define POOL_LOWER		"abcdefghijklmnopqrstuvwxyz"
#define POOL_UPPER		"ABCDEGFHIJKLMNOPQRSTUVWXYZ"
#define POOL_DIGITS		"0123456789"
#define POOL_SPECL		"/?.,><|!@#$%^&*()_+=-~;:][}{ \\\""

// -------------------------------------------------------------------------------------
// Return true if the cstring keys[ istop ] is not already contained between the
// 0th and the (istop-1)th element of the keys[] array of cstrings,
// otherwise return false
//
_Bool unique_key( const int istop, char keys[ NKEYS ][ KEYSIZE ] )
{
register int ikey = 0;

for (; ikey < istop; ikey++)
	if ( strcmp( keys[ikey], keys[istop] ) == 0 )
		return false;

return true;
}
// -------------------------------------------------------------------------------------
// This function makes sure that requested demands for keys to contain
// at least 1 char from any of the available char-sets are fulfilled
//
void apply_demanded( const unsigned char demand, char *key, const size_t keylen )
{
int i; char c;
_Bool iused[ keylen ];					// map for used i (pos)
memset(iused, false, keylen);				// zero the map

/*
 * if demanded, put a LOWER-case letter inside the key
 */
if ( demand & DEMAND_LOWER )
{
	c = POOL_LOWER[ rand() % strlen(POOL_LOWER) ];	// random LOWR letter
	i = rand() % keylen;				// random pos in key
	key[ i ] = c;					// put letter at pos
	iused[ i ] = true;				// mark pos as used
}

/*
* if demanded, put an UPPER-case letter inside the key
 */
if ( demand & DEMAND_UPPER )
{
	c = POOL_UPPER[ rand() % strlen(POOL_UPPER) ];	// random UPPR letter
	do {
		i = rand() % keylen;			// random pos in key
	} while( iused[ i ] == true );			// make sure it's unused

	key[ i ] = c;					// put letter at pos
	iused[ i ] = true;				// mark pos as used
}

/*
 * if demanded, put a DIGIT inside the key
 */
if ( demand & DEMAND_DIGITS )
{
	c = POOL_DIGITS[ rand() % strlen(POOL_DIGITS) ];// random digit
	do {
		i = rand() % keylen;			// random pos in key
	} while( iused[ i ] == true );			// make sure it's unused

	key[ i ] = c;					// put digit at pos
	iused[ i ] = true;				// mark pos as used
}

/*
 * if demanded, put a SPECIAL CHAR inside the key
 */
if ( demand & DEMAND_SPECL)
{
	c = POOL_SPECL[ rand() % strlen(POOL_SPECL) ];	// random special char
	do {
		i = rand() % keylen;			// random pos in key
	} while( iused[ i ] == true );			// make sure it's unused

	key[ i ] = c;					// put digit at pos
	iused[ i ] = true;				// mark pos as used
}

return;
}
// -------------------------------------------------------------------------------------
// Calc and return the appropriate size for the pool, based on the values of the USE_
// bits contained in: options
//
size_t pool_calcsize( const unsigned char options )
{
size_t ret = 0;

if ( options & USE_LOWER )		// make room for lower-case letters
	ret += strlen( POOL_LOWER );

if ( options & USE_UPPER )		// make room for upper-case letters
	ret += strlen( POOL_UPPER );

if ( options & USE_DIGITS )		// make room for digits
	ret += strlen( POOL_DIGITS );

if ( options & USE_SPECL )		// make room for special chars
	ret += strlen( POOL_SPECL );

return ++ret;				// make room for '\0' at the end
}
// -------------------------------------------------------------------------------------
// Initialize the chars pool, based on the values of the USE_ bits contained in: options.
// Return the initialized pool (which is as a cstring)
//
char *pool_init( char *pool, const size_t poolsize, const unsigned char options  )
{
if ( !pool )
	return NULL;

memset( pool, 0, poolsize );		// clear the pool

if ( options & USE_LOWER )		// include lower-case letters
	strncat( pool, POOL_LOWER, poolsize-1 );

if ( options & USE_UPPER )		// include upper-case letters
	strncat( pool, POOL_UPPER, poolsize-1 );

if ( options & USE_DIGITS )		// include digits
	strncat( pool, POOL_DIGITS, poolsize-1 );

if ( options & USE_SPECL )		// include special chars
	strncat( pool, POOL_SPECL, poolsize-1 );

return pool;
}
// -------------------------------------------------------------------------------------
int main( void )
{
/*
 * To disable any of the following options, delete or comment-out its
 * corresponding line below.
 *
 * 	USE_ options specify whether you want chars from that particular
 * 	char-set to participate in the key generation process or not
 *
 *	DEMAND_ options specify whether yoy want at least 1 char of that
 *	particular char-set to be included in every generated key or not
 *
 *	Note that you can disable a USE_ option without disabling its
 *	corresponding DEMAND_ option. In such cases, the disabled char-set
 *	does not generally participate in the generation process, but 1
 *	of its chars (picked randomly) will be present inside every key,
 *	at a random position.
 *
 *	To completely prevent a char-set from participating in the
 *	the generation process, delete both its USE_ and its DEMAND_ option
 */
unsigned char options =				// bit-flagged byte
		DEMAND_LOWER			// ... demand lower letter
		+ DEMAND_UPPER			// ... demand upper letter
		+ DEMAND_DIGITS			// ... demand digit
		+ DEMAND_SPECL			// ... demand special char
		+ USE_LOWER			// ... use lower letters
		+ USE_UPPER			// ... use upper letters
		+ USE_DIGITS			// ... use digits
		+ USE_SPECL			// ... use special chars
		;
const size_t POOLSIZE = pool_calcsize(options);	// calc the size of chars pool
char pool[ POOLSIZE ];				// the pool itself (cstring)
char keys[ NKEYS ][ KEYSIZE ] = { {0, 0} };	// array of (cstring) keys
int i=0, ikey=0;				// i for chars, ikey for keys

srand( time(NULL) );				// init the pseudo-random seed

pool_init( pool, POOLSIZE, options );		// initialize the chars pool

for (ikey=0; ikey < NKEYS; ikey++ )		// generate & store keys
{ 						// into the keys[NKEYS] array
	do {					// ...
		for (i=0; i < KEYSIZE-1; i++)	// ... generate a key
			keys[ ikey ][ i ] = pool[ rand() % (POOLSIZE-1) ];
	} while ( !unique_key(ikey, keys) );	// ... make sure it is unique

						// apply any char demands
	apply_demanded( options, keys[ikey], KEYSIZE-1 );

	puts( keys[ikey] );             	// print the generated key
}

return 0;
}

Δημοσ.

Παιδιά μήπως θα έπρεπε να μπει κανείς στον κόπο να ρωτήσει με ποίο τρόπο σκοπεύει ο OP να χρησιμοποιήσει τους κωδικούς αυτούς πρωτού αρχίσουμε να δίνουμε implementations και να μιλάμε για ασφαλές generation, τυχαιότητα, cryptographic strength κλπ κλπ;

Δημοσ.

Τι να ρωτήσουμε; Μπορεί να χρησιμοποιήσoυμε τους κωδικούς σε προγράμματα δικής μας παραγωγής σαν registration number για να δίνουμε στους πελάτες μας και το αντίστοιχο κλειδί λειτουργίας αν το αγοράσουν... :)

Αν κατά τύχη δύο ή περισσότερα άτομα έχουν το ίδιο registration number δεν θα το γνωρίζουν γιατί μάλλον θα είναι άγνωστα μεταξύ τους.

Δημοσ.

Η παρακάτω λύση κάνει χρήση του random number generator που έχει προστεθεί σαν χαρακτηριστικό στο C++0x. Πολύ πιθανόν να χρειάζεται σύγχρονο μεταγλωττιστή. Το πρόγραμμα έχει δοκιμαστεί με Visual C++ 2010.

 

>#include <string>
#include <iostream>
#include <ctime>
#include <algorithm>
#include <random>

const unsigned short KEY_LENGTH = 10;

std::string GetKey();

int main()
{
   for(unsigned short it = 0; it != 20; ++it)
       std::cout << it << ": " << GetKey().c_str() << "\n";
       
   return EXIT_SUCCESS;
}

std::string GetKey()
{
   std::string key;

   std::string ch("QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm1234567890`~!@#$%^&*()-_=+[]{},.<>/?'\"\\|");
   std::random_shuffle(ch.begin(), ch.end());

   std::mt19937 engine;
   engine.seed(static_cast<unsigned long>(time(NULL)));
   std::uniform_int<std::size_t> limit(0, ch.size());

   for(unsigned short it = 0; it != KEY_LENGTH; ++it)
       key += ch[limit(engine)];
	
return key;
}

 

Πιθανά αποτελέσματα:

clipboard01kw.jpg

Δημοσ.

Χαχα μικρο και καλο happy.gif

 

Να σου πω, το vs το αγορασες ή το βρηκες στο δρομο;

 

Βασικα κανει compile τιποτα απο τα παρακατω;

>enum class Foo : {foo1,foo2};
const char* FooStr = u8"Foo FOO FOOO";
const char* FeeStr = R"E:\test\foo.data";


int arr[] ={1,2};
for(int& i : arr)
{
}

 

 

Πες μου αν ειναι να παω να ψαξω στο δρομο για κανα vs γιατι το αυτο που εχω...

 

ααα υποστηριζει suffix;

Δημοσ.

Για το χαμό:

να ενημερώσω ότι τον κώδικα που δοκίμασα τους έτρεξα με visual studio 2010 (νόμιμο) :))))). Να 'ναι καλά ο αδερφός που σπουδάζει σε σχολή που έχει τα πάντα από microsoft κλπ

Δημοσ.

Χαχα μικρο και καλο happy.gif

 

Να σου πω, το vs το αγορασες ή το βρηκες στο δρομο;

 

Βασικα κανει compile τιποτα απο τα παρακατω;

>enum class Foo : {foo1,foo2};
const char* FooStr = u8"Foo FOO FOOO";
const char* FeeStr = R"E:\test\foo.data";


int arr[] ={1,2};
for(int& i : arr)
{
}

 

 

Πες μου αν ειναι να παω να ψαξω στο δρομο για κανα vs γιατι το αυτο που εχω...

 

ααα υποστηριζει suffix;

To visual studio το είχα προμηθευτεί μέσω του προγράμματος dreamspark όσο ήμουν φοιτητής στο ΤΕΙ. Δεν είναι για πέταμα αυτό που έχεις απλά όταν κυκλοφόρησε δεν είχε(έχει) πλήρη υποστήριξη του C++0x μιας και δεν υπήρχε κάποιο final draft. Οι επόμενες εκδόσεις των μεταγλωττιστών θα έχουν καλύτερη υποστήριξη λογικά.

Δημοσ.

Η παρακάτω λύση κάνει χρήση του random number generator που έχει προστεθεί σαν χαρακτηριστικό στο C++0x. Πολύ πιθανόν να χρειάζεται σύγχρονο μεταγλωττιστή. Το πρόγραμμα έχει δοκιμαστεί με Visual C++ 2010.

 

 

>#include <string>
#include <iostream>
#include <ctime>
#include <algorithm>
#include <random>

const unsigned short KEY_LENGTH = 10;

std::string GetKey();

int main()
{
   for(unsigned short it = 0; it != 20; ++it)
       std::cout << it << ": " << GetKey().c_str() << "\n";
       
   return EXIT_SUCCESS;
}

std::string GetKey()
{
   std::string key;

   std::string ch("QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm1234567890`~!@#$%^&*()-_=+[]{},.<>/?'\"\\|");
   std::random_shuffle(ch.begin(), ch.end());

   std::mt19937 engine;
   engine.seed(static_cast<unsigned long>(time(NULL)));
   std::uniform_int<std::size_t> limit(0, ch.size());

   for(unsigned short it = 0; it != KEY_LENGTH; ++it)
       key += ch[limit(engine)];
	
return key;
}

Πιθανά αποτελέσματα:

clipboard01kw.jpg

 

 

Αυτό που θεωρώ ιδιαίτερα χρήσιμο σε αυτόν τον κώδικα είναι πως είναι πλήρως εστιασμένος στη λογική και τα εργαλεία της C++ (δηλαδή είναι ανεπηρέαστος από τη φιλοσοφία της C). Είναι κάτι που εγώ τουλάχιστον δεν το συναντάω πολύ συχνά και για αυτό σε συγχαίρω φίλε 3c0r1z!

 

Αν βρεις τον χρόνο και την όρεξη, πολύ θα ήθελα να δω μια βελτιωμένη του έκδοση, που θα εξασφαλίζει την μοναδικότητα του κάθε παραγόμενου κλειδιού, καθώς και παραμετροποίηση ως προς τη συμμετοχή επιμέρους ομάδων χαρακτήρων (και συνολικά, και ως απαίτηση 1 τουλάχιστον από τους χαρακτήρες μιας ή περισσότερων ομάδων).

Δημοσ.

Αυτό που θεωρώ ιδιαίτερα χρήσιμο σε αυτόν τον κώδικα είναι πως είναι πλήρως εστιασμένος στη λογική και τα εργαλεία της C++ (δηλαδή είναι ανεπηρέαστος από τη φιλοσοφία της C). Είναι κάτι που εγώ τουλάχιστον δεν το συναντάω πολύ συχνά και για αυτό σε συγχαίρω φίλε 3c0r1z!

 

Συμφωνώ μαζί σου όσον αφορά τα συγχαρητήρια και προσθέτω και τα δικά μου. Για extra bonus points θέλει μια std::accumulate μέσα στην GetKey() αντί για for. ;-)

Αρχειοθετημένο

Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.

  • Δημιουργία νέου...