Jump to content



[C]Διάφορες απορίες (κατασκευή προγράμματος παραγωγής αριθμών με βάση τον αλγόρθμο του Luhn)


deninho

Recommended Posts

Δημοσιεύτηκε
int final_digit(int length, int a[]){	int len_offset, i, t, last, sum;		len_offset = (length)%2;	sum=0;	for (i = 0; i < length; i++)	{		if ((i + len_offset)%2 == 1)		{			t=a[i]*2;			if (t>9)			{				t=t-9;			}			sum=sum+t;		}		else		{			sum = sum + a[i];		}	}	last = (10-(sum%10))%10;	printf("%d", last);	return last;}int random_g(int min, int max){	int v;	v = rand() % max + min;	return v;}int visa_generator(){	int a[15], i, length, r;	r = random_g(1,2);	if (r == 1)	{		length = 13;	}	else if (r == 2)	{		length = 16;	}	printf("%d\n", length);	a[0] = 4;	printf("a[0] = %d\n", a[0] );	for (i=1; i<length-1; i++)	{		a[i]=random_g(0,9);		printf("a[%d] = %d\n", i, a[i] );	}	a[length-1]=final_digit(length-1, a);	printf("a[%d] = %d\n", length-1, a[15] );}

Καλησπέρα. Κάνω μια ασκησούλα για credit card number generator με τη βοήθεια του αλγορίθμου του Luhn.

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

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

Για το τελευταίο πηγαίνω στη συνάρτηση final_digit, όπου κάνω τους υπολογισμούς, και μετά επιστρέφω την τιμή στην άλλη συνάρτηση. Κι εδώ έχω το πρόβλημα:

 

Όταν η κάρτα είναι 13ψηφίων, ενώ η συνάρτηση το υπολογίζει σωστά, επιστρέφει άσχετο αποτέλεσμα.

nmvpnCh.pngUbRFGFx.pngkzHGlQP.png

ο αριθμός πριν το a[12] είναι η τιμή που θα έπρεπε να επιστραφεί (τυπωμένη μέσα από την final_digit)

 

Αντίθετα, όταν το μήκος της κάρτας είναι 16 ψηφίων, επιστρέφει σωστά την τιμή:

XMUSM8L.png

 

Any ideas?

 

ΥΓ Η main είναι ένα απλό μενού με switch, για αυτό δεν έβαλα κι αυτήν μέσα.

 

Edit: Έκανα έντιτ τον τίτλο του θέματος, μιας κι απ'ότι φαίνεται θα χρειαστώ να ρωτήσω αρκετά διαφορετικά πραγματάκια, να μην ρωτάω σε ξεχωριστά θέματα :)

lol, ντάξει, το βρήκα αυτό. Τυπώνω ως το a[15] όταν έχω γεμίσει μέχρι το a[12] λογικό να μου βγάζει βλακείες :p

Πιο σοβαρή απορία τώρα :p

 

Γενικά, το πρόγραμμα πρέπει έχει ένα μενού που θα ζητάει από το χρήστη να επιλέξει:

α. Τύπο κάρτας (American Express, Diners κλπ)

β. Πόσες κάρτες θέλει

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

 

Το πρόβλημα το έχω στο γ. Αν ήταν μόνο το ένα ή μόνο το άλλο, ευκολάκι.

 

Αυτή εδώ είναι η main (δείχνω την πρώτη επιλογή στο switch, γιατί όλα τα άλλα πλην του exit είναι ίδια)

    int main() {        int ch, n, i, print, save;        char filename[30];        FILE *fp;				srand(time(NULL));        while (1) {        		print = 0;                printf("1. AMEX \n2. Diners \n3. Maestro \n4. MasterCard\n5. Visa\n6. Visa Electron\nChoose Credit Card issuer:");                scanf("%d", &ch);                printf("Would you like to save the credit card numbers in a file? Y=1, N=0");                scanf("%d", &save);                				//If yes, we should open the file.				                if (save == 1)                {                	printf("Save as (30 characters max):");                	scanf("%s", filename);                	if ((fp = fopen(filename, "w")) == NULL)                	{                		fprintf(stderr, "Error opening file %s.", filename);                		exit(1);					}					print=1;				}                switch (ch) {                        case 1:                                printf("number of cards: ");                                scanf("%d", &n);                                for (i = 0; i < n; i++)                                {                                	AMEX_generator(fp, print);                                }                                if (print = 1)                                {                                	fclose(fp);								}                                break;...

Κι αυτή εδώ είναι η συνάρτηση που παράγει τον αριθμό της κάρτας.

int AMEX_generator(FILE *fp, int print){	int a[16], length, prefix, i, pos;	length = 15;	prefix = random_g(0,1);	if (prefix == 0)	{		a[0] = 3;		a[1] = 4;		pos = 2;	}	else if (prefix == 1)	{		a[0] = 3;		a[1] = 7;		pos = 2;	}	for (i = pos; i < length-1; i++)	{		a[i] = random_g (0,9);	}	a[length-1] = final_digit(length, a);	if (print = 0)	{		for ( i = 0; i < length; i++)		{			printf("%d", a[i]);		}		printf("\n");	}	else if (print = 1)	{		for (i = 0; i < length; i++)		{			fprintf(fp, "%d", a[i]);		}		fprintf(fp, "\n");	}}

Έτσι όπως το έχω τώρα το πρόγραμμα, αν επιλέξει ο χρήστης αποθήκευση σε αρχείο όλα καλά. Αν επιλέξει εμφάνιση στην οθόνη, επειδή ο file pointer (fp χαϊδευτικά) δεν υπάρχει για να πασαριστεί στη συνάρτηση, το πρόγραμμα ψοφάει.

 

Μία επιλογή που σκέφτηκα ήταν, σε περίπτωση που ο χρήστης θέλει εμφάνιση στην οθόνη, τη δημιουργία ενός dummy αρχείου που θα διαγράφεται μετά, το οποίο μου φαίνεται χαζό και δαπανηρό σε πόρους.

Κάτι άλλο που θα μπορούσα να κάνω θα ήταν να γράψω 2 συναρτήσεις για κάθε τύπο κάρτας, μία για εμφάνιση στην οθόνη, και μία για αποθήκευση σε αρχείο.

Υπάρχει κάποια άλλη, καλύτερη λύση;

Δεν είμαι από υπολογιστή και είναι κάπως δύσκολο να διαβάσω τον κώδικά.

Παρατήρησα στο τελευταίο fprintf(fp, "\n"); δεν έχεις βάλει %something (%c,%d etc), επίτηδες;

Επίσης από τις επιλογές που προτείνεις μου φαίνεται καλύτερη η πρώτη (με το αρχείο που θα διαγράφεται) μιας και λογικά θα χρειαστούν λιγότερα MB/KB. Γιατί;
Γιατί θα έχεις τρία αρχεία με ένα αλλά όμως. Ένα για το αρχικό πρόγραμμα, ένα για την συνάρτησης και ένα για το αρχείο που θα τυπώνετε.
Αν επιλέξει απλά να γίνεται εμφάνιση θα έχεις δύο αρχεία. Στην δεύτερη περίπτωση έχεις αναγκαστικά τρία αρχεία, ένα για το αρχικό πρόγραμμα και δύο των συναρτήσεων.

 

Είμαι και εγώ αρχάριος και πόσο μάλλον στην C, οπότε μην τα πάρεις της μετρητής.

Δεν είμαι από υπολογιστή και είναι κάπως δύσκολο να διαβάσω τον κώδικά.

Παρατήρησα στο τελευταίο fprintf(fp, "\n"); δεν έχεις βάλει %something (%c,%d etc), επίτηδες;

αλλαγή γραμμής μετά τη λούπα (η οποία τυπώνει ένα μονοδιάστατο πίνακα) :)

 

Επίσης από τις επιλογές που προτείνεις μου φαίνεται καλύτερη η πρώτη (με το αρχείο που θα διαγράφεται) μιας και λογικά θα χρειαστούν λιγότερα MB/KB. Γιατί;

Γιατί θα έχεις τρία αρχεία με ένα αλλά όμως. Ένα για το αρχικό πρόγραμμα, ένα για την συνάρτησης και ένα για το αρχείο που θα τυπώνετε.

Εδώ με μπέρδεψες :p Ένα αρχείο δε θα έχω σε κάθε περίπτωση, όσο τρέχει το πρόγραμμα;

Υπ'όψιν, πέρα από λύση, θα με ενδιέφερε και η σωστή, προγραμματιστικά, αντιμετώπιση. Δεν είμεθα μπακάληδες άλλωστε, επιστήμονες άνθρωποι είμαστε :hehe:

Νόμιζα πως την συνάρτηση την έχεις σε άλλο αρχείο και την κάνεις #include. 

Όσο αφορά τώρα τις επιλογές που δίνεις, η πρώτη λογικά θα είναι πιο "δαπανηρή" με το dummy αρχείο αλλά αρκετά πιο εύκολη στην υλοποίηση της. Θα έχεις αρκετά λιγότερο κώδικα.
Η δεύτερη είναι σωστότερη αλλά ο κώδικας σου θα είναι πιο σύνθετος. Βέβαια απ' ότι κατάλαβα δεν ψάχνεις τον εύκολο τρόπο, οπότε ψηφίζω το δεύτερη επιλογή.

Να αλλάξεις τις συναρτήσεις που παράγουν τους αριθμούς των καρτών ώστε να τα επιστρέφουν πάντα σε ένα πίνακα και μετά να βλέπεις αν πρέπει να τα εκτυπώσεις σε αρχείο ή στο standard output.

Πέρφεκτ :T:

 

jic που θα το ψάχνει κάποιος άλλος, για να περάσεις array από function σε main:

int *function(){static int array............return array;}
void main(){int *p;...p = function();for (i=0; i < kati; i++){printf("%d", *(p+i));}...}

Τέλος αυτό το πρόγραμμα :p

  • 2 weeks later...

Επειδή μου έχουν σπάσει τα νεύρα... Υπάρχει τρόπος, έναν αριθμό με πολλά ψηφία (τουλάχιστον 13) που μου δίνει ο χρήστης, να τον αποθηκεύω σε array, ένα ψηφίο ανά θέση; προς το παρόν αποθηκεύω τον αριθμό σε μια μεταβλητή long long και μετά με mod & διαίρεση, με 10, το περνάω σε πίνακα. Αναρωτιέμαι αν μπορώ να γλυτώσω το long long, που για κάποιο λόγο δε μου λειτουργεί στο dev-c++...

Η εύκολη λύση είναι να τα ζητάς από τον χρήστη ψηφίο ψηφίο.

 

Αν δεν το θες αυτό μπορείς να το διαβάσεις σαν "string" (array από chars) και μετά να το βάλεις σε ένα array απο int κάνοντας και τον απλό έλεγχο αν είναι ψηφίο πχ με την isdigit http://www.cplusplus.com/reference/cctype/isdigit/

Επειδή μου έχουν σπάσει τα νεύρα... Υπάρχει τρόπος, έναν αριθμό με πολλά ψηφία (τουλάχιστον 13) που μου δίνει ο χρήστης, να τον αποθηκεύω σε array, ένα ψηφίο ανά θέση; προς το παρόν αποθηκεύω τον αριθμό σε μια μεταβλητή long long και μετά με mod & διαίρεση, με 10, το περνάω σε πίνακα. Αναρωτιέμαι αν μπορώ να γλυτώσω το long long, που για κάποιο λόγο δε μου λειτουργεί στο dev-c++...

 

Παίρνοντας το modulus 10 παίρνεις το τελευταίο ψηφίο, μετά διαιρείς με 10 και ξανακάνεις το ίδιο.

 

Π.χ

123%10 = 3

123/10 = 12

 

12%10 = 2

12/10 = 1

 

1%10 = 1

ναι, αυτό κάνω τώρα, αλλά πρέπει πρώτα να τον αποθηκεύσω κάπου τον αριθμό, και είναι αυτό που ήθελα να αποφύγω :)

Archived

This topic is now archived and is closed to further replies.

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

Important Information

Ο ιστότοπος theLab.gr χρησιμοποιεί cookies για να διασφαλίσει την καλύτερη εμπειρία σας κατά την περιήγηση. Μπορείτε να προσαρμόσετε τις ρυθμίσεις των cookies σας , διαφορετικά θα υποθέσουμε ότι είστε εντάξει για να συνεχίσετε.