/* * Tutkitaan RF-viitteen oikeellisuutta * * Muoto: RFttxx * missä RF on vakiomerkkijono, * tt on 2-numeroinen tarkiste ja * xx on 1-21 aakkosnumeerisen merkin (0-9A-Z) jono * * Seassa saa olla yksittäisiä tyhjiä ja pienet kirjaimet samaistetaan isoiksi. * Tarkisteen lasku: * (1) lisätään xx:n loppuun "RF00" * (2) muunnetaan kirjaimet numeroiksi tyyliin A->10, B->11 jne * (3) lasketaan tuloksesta jakojäännös 97:llä jaettaessa * (4) tarkiste on 98 - jakojäännös */ #include #include #include #include #include #define VALIDMAX 25 #define VALIDMIN 5 #define MAXLEN (2*VALIDMAX) /* varataan tilaa myös välityhjille */ /* apumakroja debuggaukseen */ #ifdef DEBUG #define DPRINT1(a,b) fprintf(stderr,(a),(b)) #define DPRINT2(a,b,c) fprintf(stderr,(a),(b),(c)) #else #define DPRINT1(a,b) #define DPRINT2(a,b,c) #endif void tarkista_alku(const char viite[]); void lisaa_normalisoituna(const char *lahde, char kohde[], int maxpituus); char * normalisoi(const char viite[]); int longmod97(char *longnum); void tarkistusmerkkitesti(int laskettu, char viite[]); void virhe(char *fmt, int n); int main(int argc, char **argv) { char viite[MAXLEN + 1] = ""; char *numviite; int jakoj, tarknro, i; if (argc < 2) { printf("Anna viite: "); fgets(viite, MAXLEN, stdin); } else { for (i=1; i 10-35 (ei toimi EBCDIC-koneissa...) */ #define LETTER2NUM(letter) ((letter) - 'A' + 10) void lisaa_normalisoituna(const char *lahde, char kohde[], int maxpituus) { DPRINT2("normalisoidaan '%s' (%lu merkkiä)\n", lahde, strlen(lahde)); for (; *lahde; lahde++) { if (isspace(*lahde)) { continue; } else if (--maxpituus < 0) { virhe("Liian pitka (maks. %d merkkia)", VALIDMAX); } else if (isdigit(*lahde)) { *kohde++ = *lahde; DPRINT2("%c -> %c\n", *lahde, *lahde); } else if (isalpha(*lahde)) { int k = LETTER2NUM(toupper(*lahde)); *kohde++ = '0' + k/10; *kohde++ = '0' + k%10; DPRINT2("%c -> %d\n", *lahde, k); } else { virhe("Laiton merkki '%c'", *lahde); } } } /* lasketaan merkkijonona annetusta kokonaisluvusta modulo 97 */ /* lasketaan numero kerrallaan ja otetaan joka vaiheessa %97 ylivuodon */ /* estämiseksi käyttäen kaavaa (a+b)%97 == (a%97) +c)%97 */ int longmod97(char *longnum) { int result; result = 0; for (; *longnum; ++longnum) { result = (result*10 + (*longnum - '0')) % 97; } return result; } /******************************************************************/