Jump to content



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


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: Έκανα έντιτ τον τίτλο του θέματος, μιας κι απ'ότι φαίνεται θα χρειαστώ να ρωτήσω αρκετά διαφορετικά πραγματάκια, να μην ρωτάω σε ξεχωριστά θέματα :)

Link to comment
Share on other sites

Πιο σοβαρή απορία τώρα :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 συναρτήσεις για κάθε τύπο κάρτας, μία για εμφάνιση στην οθόνη, και μία για αποθήκευση σε αρχείο.

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

Link to comment
Share on other sites

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

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

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

 

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

Έγινε επεξεργασία από UltraB
Link to comment
Share on other sites

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

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

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

 

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

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

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

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

Link to comment
Share on other sites

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

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

Link to comment
Share on other sites

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

  • Like 1
Link to comment
Share on other sites

Πέρφεκτ :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

Link to comment
Share on other sites

  • 2 weeks later...

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

Link to comment
Share on other sites

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

 

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

  • Like 1
Link to comment
Share on other sites

Επειδή μου έχουν σπάσει τα νεύρα... Υπάρχει τρόπος, έναν αριθμό με πολλά ψηφία (τουλάχιστον 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

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

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

Important Information

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