Listing 2 Algorithm for calculating HL-7 standard check digits

/*
* This implementation of the above algorithm has some distinct
* limitations, although I believe they are not a serious problem.
* This is intended for processing short strings of digits (10 or so),
* not arbitrarily long digit strings. Each of the substrings that are
* broken out by the code below are assumed to be a value that can
* be assigned to a long when converted to an integral type. This
* limitation requires that the input string not be more than about 20
* characters in length, which is more than adequate for the intended
* application. I'm assuming that a long is at least 32 bits.
* Further, it assumes a character set where the digits' collating
* sequence mimics that of ASCII, so that things like:
*      x = val - '0';
* will evaluate to an integer value of 3 in the case where val == '3'.
*/

#include <stdio.h>
#define MOD10 10
#define MOD11 11
/*
* -------------- - check_digit() -------- -  *
* Calculates a check digit according to the algorithm given above.
* NOTE
* that there are no checks for array bounds overflow. Beware.
*/
    check_digit (string, mod)
    char * string;
    int mod;
        {
        char tmpbuf[20];
        int i, j, sum;
        unsigned long odd, even;
    /* extract the odd digits */
    j = strlen (string);
    for ( j-, i = 0 ; j >= 0 ; j -= 2, i++ )
        {
        tmpbuf[i] = string[j];
        }
    tmpbuf[i] = '\0';
    odd = atol (tmpbuf);
    /* extract the even digits */
    j = strlen (string);
    for ( j -= 2, i = 0 ; j >= 0 ; j -= 2, i++ )
        {
        tmpbuf[i] = string[j];
        }
        tmpbuf[i] = '\0';
        even = atol (tmpbuf);
    /* now make the composite string & sum the digits */
    sprintf (tmpbuf, "%lu%lu", even, 2L * odd);
    i = strlen (tmpbuf);
    for ( sum = j = 0 ; j < i ; j++)
        {
        sum += tmpbuf[j] - '0';
        }
    /* now do the mod10 or mod11 operation */
     i = (mod - (sum % mod));
    if (i == mod)
        i = 0;
    return (i);
    }
#ifdef TEST
    main ()
    {
     char buf[30];
    while (1)
        {
        gets (buf);
        if (strlen (buf) == 0)
            break;
        printf ("string: %s, mod10 checkdigit: %d,"
            "mod11 checkdigit %d:n",
            buf, check_digit (buf, MOD10),
            check_digit (buf, MOD11));
        }
    }
#endif /* TEST */

/* End of File */