/*TITLE test program for radix40 conversions */ #include #include #include #include #include #define STRING_LENGTH 12 #define REPS 4000 #define S_OKAY 0 #define S_ILLEGAL 1 #define HYPHEN 2 typedef unsigned Radix40; main() { int i; unsigned char test[STRING_LENGTH+1] = "Radix40 Test"; Radix40 temp[STRING_LENGTH]; unsigned char test2[STRING_LENGTH+1]; clock_t start, end; start = clock(); for (i = 0; i < REPS; i ++) ascii_to_radix40_1(temp,test,STRING_LENGTH); end = clock(); printf("Timer ticks for version 1: %d\n",end-start); radix40_to_ascii(temp,test2,STRING_LENGTH); if (stricmp(test2,test) != 0) printf("Match 1 failed\n"); start = clock(); for (i = 0; i < REPS; i ++) ascii_to_radix40_2(temp,test,STRING_LENGTH); end = clock(); printf("Timer ticks for version 2: %d\n",end-start); radix40_to_ascii(temp,test2,STRING_LENGTH); if (stricmp(test2,test) != 0) printf("Match 2 failed\n"); start = clock(); for (i = 0; i < REPS; i ++) ascii_to_radix40_3(temp,test,STRING_LENGTH); end = clock(); printf("Timer ticks for version 3: %d\n",end-start); radix40_to_ascii(temp,test2,STRING_LENGTH); if (stricmp(test2,test) != 0) printf("Match 3 failed\n"); start = clock(); for (i = 0; i < REPS; i ++) ascii_to_radix40_4(temp,test,STRING_LENGTH); end = clock(); printf("Timer ticks for version 4: %d\n",end-start); radix40_to_ascii_4(temp,test2,STRING_LENGTH); if (stricmp(test2,test) != 0) printf("Match 4 failed\n"); } unsigned char legal_chars[] = " ,-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; unsigned weights[3] = {1600, 40, 1}; #define STACK_DATA_SIZE 100 /* updoc ascii_to_radix40 */ int ascii_to_radix40_1(radix40_data,ascii_data,max_chars) unsigned *radix40_data; unsigned char *ascii_data; int max_chars; /* this routine converts a null-terminated ascii character string */ /* to radix 40 representation. The allowable characters are: */ /* A-Z, 0-9, period, comma, hyphen, and space. If any illegal characters */ /* are detected, they will be converted to hyphens, and the return value */ /* will be S_ILLEGAL. */ /* Lowercase letters will be upper-cased without error indication. */ /* The radix40 value will be padded with blanks to a multiple of three */ /* characters. If the number of characters in the ascii string is > max_chars */ /* only max_chars will be converted, and the return value will be S_ILLEGAL. */ /* If no error is detected, the return value will be S_OKAY. */ /* updoc end */ { int i; int j; int ascii_length; int result; int conversion_status; int words_to_convert; int words_to_clear; int cycle; unsigned current_word_index; result = 0; ascii_length = strlen(ascii_data); if (ascii_length > max_chars) { ascii_length = max_chars; result = S_ILLEGAL; } words_to_convert = ascii_length / 3; if (ascii_length % 3 != 0) words_to_convert ++; words_to_clear = max_chars / 3; if (max_chars % 3 != 0) words_to_clear ++; for (i = 0; i < words_to_clear; i ++) radix40_data[i] = 0; /* this blanks out the output string */ current_word_index = -1; cycle = 0; for (i = 0; i < ascii_length; i ++) { if (cycle == 0) current_word_index ++; conversion_status = 0; for (j = 0; j < 40; j ++) if (legal_chars[j] == toupper(ascii_data[i])) { conversion_status = 1; break; } if (conversion_status == 0) { result = S_ILLEGAL; j = HYPHEN; /* code for hyphen */ } radix40_data[current_word_index] += weights[cycle] * j; cycle = (cycle + 1) % 3; } return(result); } /* updoc ascii_to_radix40 */ int ascii_to_radix40_2(radix40_data,ascii_data,max_chars) unsigned *radix40_data; unsigned char *ascii_data; int max_chars; /* this routine converts a null-terminated ascii character string */ /* to radix 40 representation. The allowable characters are: */ /* A-Z, 0-9, period, comma, hyphen, and space. If any illegal characters */ /* are detected, they will be converted to hyphens, and the return value */ /* will be S_ILLEGAL. */ /* Lowercase letters will be upper-cased without error indication. */ /* The radix40 value will be padded with blanks to a multiple of three */ /* characters. If the number of characters in the ascii string is > max_chars */ /* only max_chars will be converted, and the return value will be S_ILLEGAL. */ /* If no error is detected, the return value will be S_OKAY. */ /* updoc end */ { int i; int j; int ascii_length; int result; int conversion_status; int words_to_convert; int words_to_clear; int cycle; unsigned current_word_index; unsigned char *temp_ascii_data; result = 0; ascii_length = strlen(ascii_data); if (ascii_length > max_chars) { ascii_length = max_chars; result = S_ILLEGAL; } temp_ascii_data = malloc(ascii_length+1); for (i = 0; i < ascii_length+1; i ++) temp_ascii_data[i] = toupper(ascii_data[i]); words_to_convert = ascii_length / 3; if (ascii_length % 3 != 0) words_to_convert ++; words_to_clear = max_chars / 3; if (max_chars % 3 != 0) words_to_clear ++; for (i = 0; i < words_to_clear; i ++) radix40_data[i] = 0; /* this blanks out the output string */ current_word_index = -1; cycle = 0; for (i = 0; i < ascii_length; i ++) { if (cycle == 0) current_word_index ++; conversion_status = 0; for (j = 0; j < 40; j ++) if (legal_chars[j] == temp_ascii_data[i]) { conversion_status = 1; break; } if (conversion_status == 0) { result = S_ILLEGAL; j = HYPHEN; /* code for hyphen */ } radix40_data[current_word_index] += weights[cycle] * j; cycle = (cycle + 1) % 3; } free(temp_ascii_data); return(result); } /* updoc ascii_to_radix40 */ int ascii_to_radix40_3(radix40_data,ascii_data,max_chars) unsigned *radix40_data; unsigned char *ascii_data; int max_chars; /* this routine converts a null-terminated ascii character string */ /* to radix 40 representation. The allowable characters are: */ /* A-Z, 0-9, period, comma, hyphen, and space. If any illegal characters */ /* are detected, they will be converted to hyphens, and the return value */ /* will be S_ILLEGAL. */ /* Lowercase letters will be upper-cased without error indication. */ /* The radix40 value will be padded with blanks to a multiple of three */ /* characters. If the number of characters in the ascii string is > max_chars */ /* only max_chars will be converted, and the return value will be S_ILLEGAL. */ /* If no error is detected, the return value will be S_OKAY. */ /* updoc end */ { int i; int j; int ascii_length; int result; int conversion_status; int words_to_convert; int words_to_clear; int cycle; unsigned current_word_index; unsigned char *temp_ascii_data; unsigned char stack_ascii_data[STACK_DATA_SIZE]; result = 0; ascii_length = strlen(ascii_data); if (ascii_length > max_chars) { ascii_length = max_chars; result = S_ILLEGAL; } if (ascii_length < STACK_DATA_SIZE) temp_ascii_data = stack_ascii_data; else temp_ascii_data = malloc(ascii_length+1); for (i = 0; i < ascii_length+1; i ++) temp_ascii_data[i] = toupper(ascii_data[i]); words_to_convert = ascii_length / 3; if (ascii_length % 3 != 0) words_to_convert ++; words_to_clear = max_chars / 3; if (max_chars % 3 != 0) words_to_clear ++; for (i = 0; i < words_to_clear; i ++) radix40_data[i] = 0; /* this blanks out the output string */ current_word_index = -1; cycle = 0; for (i = 0; i < ascii_length; i ++) { if (cycle == 0) current_word_index ++; conversion_status = 0; for (j = 0; j < 40; j ++) if (legal_chars[j] == temp_ascii_data[i]) { conversion_status = 1; break; } if (conversion_status == 0) { result = S_ILLEGAL; j = HYPHEN; /* code for hyphen */ } radix40_data[current_word_index] += weights[cycle] * j; cycle = (cycle + 1) % 3; } if (ascii_length >= STACK_DATA_SIZE) free(temp_ascii_data); return(result); } #define IL 0x82 /* this is the code for a -, but with the illegal flag set */ char lookup_chars[256] = {IL, IL, IL, IL, IL, IL, IL, IL,/* 00 */ IL, IL, IL, IL, IL, IL, IL, IL, /* 08 */ IL, IL, IL, IL, IL, IL, IL, IL, /* 10 */ IL, IL, IL, IL, IL, IL, IL, IL, /* 18 */ 0, IL, IL, IL, IL, IL, IL, IL, /* 20 */ IL, IL, IL, IL, 1, 2, 3, IL, /* 28 */ 4, 5, 6, 7, 8, 9, 10, 11, /* 30 */ 12, 13 ,IL, IL, IL, IL, IL, IL, /* 38 */ IL, 14, 15, 16, 17, 18, 19, 20, /* 40 */ 21, 22, 23, 24, 25, 26, 27, 28, /* 48 */ 29, 30, 31, 32, 33, 34, 35, 36, /* 50 */ 37, 38, 39, IL, IL, IL, IL, IL, /* 58 */ IL, 14, 15, 16, 17, 18, 19, 20, /* 60 */ 21, 22, 23, 24, 25, 26, 27, 28, /* 68 */ 29, 30, 31, 32, 33, 34, 35, 36, /* 70 */ 37, 38, 39, IL, IL, IL, IL, IL, /* 78 */ IL, IL, IL, IL, IL, IL, IL, IL, /* 80 */ IL, IL, IL, IL, IL, IL, IL, IL, /* 88 */ IL, IL, IL, IL, IL, IL, IL, IL, /* 90 */ IL, IL, IL, IL, IL, IL, IL, IL, /* 98 */ IL, IL, IL, IL, IL, IL, IL, IL, /* A0 */ IL, IL, IL, IL, IL, IL, IL, IL, /* A8 */ IL, IL, IL, IL, IL, IL, IL, IL, /* B0 */ IL, IL, IL, IL, IL, IL, IL, IL, /* B8 */ IL, IL, IL, IL, IL, IL, IL, IL, /* C0 */ IL, IL, IL, IL, IL, IL, IL, IL, /* C8 */ IL, IL, IL, IL, IL, IL, IL, IL, /* D0 */ IL, IL, IL, IL, IL, IL, IL, IL, /* D8 */ IL, IL, IL, IL, IL, IL, IL, IL, /* E0 */ IL, IL, IL, IL, IL, IL, IL, IL, /* E8 */ IL, IL, IL, IL, IL, IL, IL, IL, /* F0 */ IL, IL, IL, IL, IL, IL, IL, IL};/* F8 */ /* updoc ascii_to_radix40 */ int ascii_to_radix40_4(radix40_data,ascii_data,max_chars) unsigned *radix40_data; unsigned char *ascii_data; int max_chars; /* this routine converts a null-terminated ascii character string */ /* to radix 40 representation. The allowable characters are: */ /* A-Z, 0-9, period, comma, hyphen, and space. If any illegal characters */ /* are detected, they will be converted to hyphens, and the return value */ /* will be S_ILLEGAL. */ /* Lowercase letters will be upper-cased without error indication. */ /* The radix40 value will be padded with blanks to a multiple of three */ /* characters. If the number of characters in the ascii string is > max_chars */ /* only max_chars will be converted, and the return value will be S_ILLEGAL. */ /* If no error is detected, the return value will be S_OKAY. */ /* updoc end */ { int i; int j; int ascii_length; int result; int words_to_convert; int words_to_clear; int cycle; unsigned current_word_index; result = S_OKAY; ascii_length = strlen(ascii_data); if (ascii_length > max_chars) { ascii_length = max_chars; result = S_ILLEGAL; } words_to_convert = ascii_length / 3; if (ascii_length % 3 != 0) words_to_convert ++; words_to_clear = max_chars / 3; if (max_chars % 3 != 0) words_to_clear ++; memset(radix40_data,0,words_to_clear*sizeof(Radix40)); current_word_index = -1; cycle = 0; for (i = 0; i < ascii_length; i ++) { if (cycle == 0) current_word_index ++; j = lookup_chars[ascii_data[i]]; if (j & 0x80) { j = j & 0x7f; result = S_ILLEGAL; } radix40_data[current_word_index] += weights[cycle] * j; cycle = (cycle + 1) % 3; } return(result); } /* updoc radix40_to_ascii */ int radix40_to_ascii(radix40_data,ascii_data,max_chars) unsigned *radix40_data; unsigned char *ascii_data; int max_chars; /* this routine converts a radix 40 character string */ /* to ascii representation. Trailing blanks will be deleted. */ /* updoc end */ { int i; int j; int ascii_length; int new_ascii_length; int words_to_convert; int cycle; unsigned current_word_index; unsigned current_word; unsigned current_char; ascii_length = max_chars; words_to_convert = ascii_length / 3; if (ascii_length % 3 != 0) words_to_convert ++; for (i = 0; i < max_chars + 1; i ++) ascii_data[i] = 0; /* this nulls out the output string */ current_word_index = -1; cycle = 0; for (i = 0; i < ascii_length; i ++) { if (cycle == 0) { current_word_index ++; current_word = radix40_data[current_word_index]; } current_char = current_word / weights[cycle]; current_word -= current_char * weights[cycle]; ascii_data[i] = legal_chars[current_char]; cycle = (cycle + 1) % 3; } new_ascii_length = strlen(ascii_data); for (i = new_ascii_length - 1; i >= 0; i --) { if (ascii_data[i] != ' ') break; ascii_data[i] = 0; } return(S_OKAY); } /* updoc radix40_to_ascii */ int radix40_to_ascii_4(radix40_data,ascii_data,max_chars) unsigned *radix40_data; unsigned char *ascii_data; int max_chars; /* this routine converts a radix 40 character string */ /* to ascii representation. Trailing blanks will be deleted. */ /* updoc end */ { int i; int j; int ascii_length; int new_ascii_length; int words_to_convert; int cycle; unsigned current_word_index; unsigned current_word; unsigned current_char; ascii_length = max_chars; words_to_convert = ascii_length / 3; if (ascii_length % 3 != 0) words_to_convert ++; for (i = 0; i < max_chars + 1; i ++) ascii_data[i] = 0; /* this nulls out the output string */ current_word_index = -1; cycle = 0; for (i = 0; i < ascii_length; i ++) { if (cycle == 0) { current_word_index ++; current_word = radix40_data[current_word_index]; } current_char = current_word / weights[cycle]; current_word -= current_char * weights[cycle]; ascii_data[i] = legal_chars[current_char]; cycle = (cycle + 1) % 3; } new_ascii_length = strlen(ascii_data); for (i = new_ascii_length - 1; i >= 0; i --) { if (ascii_data[i] != ' ') break; ascii_data[i] = 0; } return(S_OKAY); }