home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / snip9707.zip / MODULUS.C < prev    next >
C/C++ Source or Header  |  1997-07-05  |  18KB  |  376 lines

  1. /* +++Date last modified: 05-Jul-1997 */
  2.  
  3. /****************************************************************************
  4. * @(#)MODULUS.c
  5. * @(#)- Basic routines for creating and checking modulus values
  6. *
  7. *
  8. *****************************************************************************
  9. * CONTENTS:
  10. *
  11. *   modulus10() ;        Returns the modulus 10 check digit.
  12. *   modulus11() ;        Returns the modulus 11 check digit
  13. *   check_modulus10() ;  Checks if the check digit in string is correct
  14. *   check_modulus11() ;  Checks if the check digit in string is correct
  15. *
  16. *****************************************************************************
  17. * DESCRIPTION:
  18. *
  19. * Calculations of modulus 10 check digits:
  20. *
  21. *   Multiply units position an every       Base 6 1 2 4 8
  22. *   alternate position i basic code             6   2   8
  23. *   number by 2, starting from righthand
  24. *   digit                                                 = 1256
  25. *
  26. *   Bring down digits that were not               1   4
  27. *   multiplied by 2
  28. *
  29. *   Cross add these digits to digits in
  30. *   first product                             1+2+5+6+1+4 = 19
  31. *
  32. *   Enter next higher number with a ending
  33. *   zero. If the number already ends with
  34. *   zero keep it.                                           20
  35. *
  36. *   Subtract the cross add sum with next
  37. *   higher and you've got the check digit         20 - 19 = 1
  38. *                                                           ═
  39. *   Result : 61248 1
  40. *
  41. *
  42. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  43. *
  44. * Calculations of modulus 11 check digits:
  45. *
  46. *   Assigned weighted checking factor    base       9 4 3 4 5 7 8 4 2
  47. *   to each digits position of basic     weight     4 3 2 7 6 5 4 3 2
  48. *   code number starting with units
  49. *   position of number and progressing
  50. *   to most significant digit
  51. *
  52. *   Weight used is:
  53. *   765432765432765432765432765432765432 etc.
  54. *
  55. *   Multiply esch digit of the basic               36
  56. *   code number by its weighted checking             12
  57. *   factor, and add the products                        6
  58. *                                                        28
  59. *                                                          30
  60. *                                                            35
  61. *                                                              32
  62. *                                                                12
  63. *                                                                   4
  64. *
  65. *
  66. *                                                            Sum = 195
  67. *
  68. *   Divide Sum of products by 11                  195 % 11 = 17 plus
  69. remainder of 8
  70. *
  71. *   Subtract remainder from 11                    11 - 8 = 3
  72. *   difference is check digit                              ═
  73. *
  74. *   Result :  943457842 3
  75. *
  76. *****************************************************************************
  77. *@(#)1993 Erik Bachmann (E-mail: ebp@dde.dk)
  78. *
  79. * Released to public domain 27-Oct-95
  80. *****************************************************************************/
  81. #include <math.h>                      /* pow() */
  82. #include <string.h>                    /* strlen(), strncpy() */
  83. #include "bacstd.h"
  84.  
  85.  
  86. /*
  87.  /-------------------------------------\
  88. |      MODULUS10                        |------------------------------------|
  89. |\-------------------------------------/                                    
  90. |                                                                            
  91. |                                                                            
  92. |----------------------------------------------------------------------------|
  93. | CALL:                                                                      
  94. |    iMod10 = modulus10("61248") ;                                            
  95. |                                                                            
  96. | HEADER:                                                                    
  97. |    math.h        pow()                                                     
  98. |                                                                            
  99. | GLOBALE VARIABLES:                                                         
  100. |    %                                                                       
  101. |                                                                            
  102. | ARGUMENTS:                                                                 
  103. |    char *pszBase                                                           
  104. |                  The string on which the modulus is performed              
  105. |                                                                            
  106. |                                                                            
  107. | PROTOTYPE:                                                                 
  108. |    int _CfnTYPE modulus10(char *pszBase) ;                                  
  109. |                                                                            
  110. | RETURN VALUE:                                                              
  111. |    int           Modulus value                                             
  112. |                                                                            
  113. | MODULE:                                                                    
  114. |    modulus.c                                                               
  115. |----------------------------------------------------------------------------|
  116. |                                                                            
  117. |                                                                            
  118. |----------------------------------------------------------------------------|
  119. |1993-09-29/Erik Bachmann                                                    
  120. \---------------------------------------------------------------------------|*/
  121.  
  122. int _CfnTYPE modulus10(char *pszBase)
  123. {
  124.    int   iSum  = 0,
  125.          iTemp = 0,
  126.          i,
  127.          j ;
  128.  
  129.    /*--------------------------------*/
  130.  
  131.                                        /* Get units position an every
  132.                                           alternate position i basic code,
  133.                                           starting from righthand and
  134.                                           cross add */
  135.    for (i = strlen(pszBase) - 1, j = 0 ; i >= 0 ; i -= 2, j++ )
  136.    {
  137.       iSum += (pszBase[i] - '0') * (int)pow(10, j) ;
  138.    }
  139.  
  140.    iSum *= 2 ;                         /* Multiply by 2 */
  141.  
  142.    iTemp = iSum ;
  143.                                        /* Bring down digits that were not
  144.                                           multiplied by 2 */
  145.    for ( iSum = 0 ; j >= 0 ; j--)
  146.    {
  147.       iSum  += iTemp % 10 ;               /* Cross add these digits to digits in
  148.                                           first product */
  149.       iTemp /= 10 ;
  150.    }
  151.                                        /* Enter next higher number with a
  152.                                           ending zero. If the number already
  153.                                           ends with zero keep it. */
  154.  
  155.    for (i = strlen(pszBase) - 2 ; i >= 0 ; i -= 2 )
  156.    {
  157.       iSum += (pszBase[i] - '0') ;
  158.    }
  159.  
  160.                                        /* Subtract the cross add sum with
  161.                                           next higher and you've got the
  162.                                           check digit*/
  163.    if ( (iSum % 10) != 0)
  164.    {
  165.       iSum = ( ( (iSum / 10) + 1 ) * 10) - iSum ;
  166.    }
  167.    else
  168.       iSum = 0 ;
  169.  
  170.    return( iSum ) ;
  171. }  /*** modulus10() ***/
  172.  
  173.  
  174. /*
  175.  /-------------------------------------\
  176. |      MODULUS11                        |------------------------------------|
  177. |\-------------------------------------/                                    
  178. |                                                                            
  179. |                                                                            
  180. |----------------------------------------------------------------------------|
  181. | CALL:                                                                      
  182. |    iMod11 = modulus11("943457842") ;                                        
  183. |                                                                            
  184. | HEADER:                                                                    
  185. |    math.h        pow()                                                     
  186. |                                                                            
  187. | GLOBALE VARIABLES:                                                         
  188. |    %                                                                       
  189. |                                                                            
  190. | ARGUMENTS:                                                                 
  191. |    char *pszBase                                                           
  192. |                  The string on which the modulus is performed    
  193. |                                                                            
  194. | PROTOTYPE:                                                                 
  195. |    int _CfnTYPE modulus11(char *pszBase) ;                                  
  196. |                                                                            
  197. | RETURN VALUE:                                                              
  198. |    int           Modulus value                                             
  199. |                                                                            
  200. | MODULE:                                                                    
  201. |    modulus.c                                                               
  202. |----------------------------------------------------------------------------|
  203. |                                                                            
  204. |                                                                            
  205. |----------------------------------------------------------------------------|
  206. |1993-09-29/Erik Bachmann                                                    
  207. \---------------------------------------------------------------------------|*/
  208.  
  209. int _CfnTYPE modulus11(char *pszBase)
  210. {
  211.    char *pszWeids = "765432" ;
  212.    int   iSum = 0 ;
  213.    int   i,
  214.          j ;
  215.  
  216.    /*--------------------------*/
  217.  
  218.                                        /* Assigned weighted checking factor
  219.                                           to each digits position of basic
  220.                                           code number starting with units
  221.                                           position of number and progressing
  222.                                           to most significant digit */
  223.  
  224.    for ( i = strlen(pszBase) - 1, j = 5 ; i >= 0 ; i-- )
  225.    {
  226.                                        /* Multiply esch digit of the basic
  227.                                           code number by its weighted checking
  228.                                           factor, and add the products */
  229.       iSum += (pszBase[i] - '0') * (pszWeids[j--] - '0') ;
  230.       if (j < 0)
  231.          j = 5 ;
  232.    }
  233.  
  234.                                        /* Divide Sum of products by 11
  235.                                           Subtract remainder from 11
  236.                                           difference is check digit */
  237.    iSum = 11 - (iSum % 11) ;
  238.  
  239.    return( iSum ) ;
  240. }  /*** modulus11() ***/
  241.  
  242.  
  243. /*--------------------------------------------------------------*/
  244.  
  245. /*
  246.  /-------------------------------------\
  247. |      CHECK_MODULUS10                  |------------------------------------|
  248. |\-------------------------------------/                                    
  249. |                                                                            
  250. |                                                                            
  251. |----------------------------------------------------------------------------|
  252. | CALL:                                                                      
  253. |    iMod10 = check_modulus10("612481") ;                                     
  254. |                                                                            
  255. | HEADER:                                                                    
  256. |    math.h        pow()                                                     
  257. |                                                                            
  258. | GLOBALE VARIABLES:                                                         
  259. |    %                                                                       
  260. |                                                                            
  261. | ARGUMENTS:                                                                 
  262. |    char *pszBase                                                           
  263. |                  The string including the digit to be checked              
  264. |                                                                            
  265. |                                                                            
  266. | PROTOTYPE:                                                                 
  267. |    int _CfnTYPE check_modulus10(char *pszBase) ;                            
  268. |                                                                            
  269. | RETURN VALUE:                                                              
  270. |    int           0     = OK                                                
  271. |                  else    value - 10 = correct digit                        
  272. | MODULE:                                                                    
  273. |    modulus.c                                                               
  274. |----------------------------------------------------------------------------|
  275. |                                                                            
  276. |                                                                            
  277. |----------------------------------------------------------------------------|
  278. |1993-09-29/Erik Bachmann                                                    
  279. \---------------------------------------------------------------------------|*/
  280.  
  281. int _CfnTYPE check_modulus10(char *pszBase)
  282. {
  283.    char  szTmp[11] ;
  284.    int   iTmp = 0 ;
  285.  
  286.    /*--------------------*/
  287.  
  288.    strncpy(szTmp, pszBase, strlen(pszBase) - 1) ;
  289.    szTmp[strlen(pszBase) - 1] = '\0' ;
  290.                                        /* Extract base */
  291.    iTmp = pszBase[strlen(pszBase) - 1] - '0' ;
  292.                                        /* Extract current check digit */
  293.    if ( modulus10(szTmp) == iTmp )
  294.       return( 0 ) ;                    /* Check digit is OK */
  295.    else
  296.       return( 10 + modulus10(szTmp) ) ;/* On error return the correct + 10 */
  297. }  /*** check_modulus10() ***/
  298.  
  299. /*--------------------------------------------------------------*/
  300.  
  301. /*
  302.  /-------------------------------------\
  303. |      CHECK_MODULUS11                  |------------------------------------|
  304. |\-------------------------------------/                                    
  305. |                                                                            
  306. |                                                                            
  307. |----------------------------------------------------------------------------|
  308. | CALL:                                                                      
  309. |    iMod11 = check_modulus11("9434578423") ;                                 
  310. |                                                                            
  311. | HEADER:                                                                    
  312. |    math.h        pow()                                                     
  313. |                                                                            
  314. | GLOBALE VARIABLES:                                                         
  315. |    %                                                                       
  316. |                                                                            
  317. | ARGUMENTS:                                                                 
  318. |    char *pszBase                                                           
  319. |                  The string including the digit to be checked              
  320. |                                                                            
  321. |                                                                            
  322. | PROTOTYPE:                                                                 
  323. |    int _CfnTYPE check_modulus10(char *pszBase) ;                            
  324. |                                                                            
  325. | RETURN VALUE:                                                              
  326. |    int           0     = OK                                                
  327. |                  else    value - 11 = correct digit                        
  328. | MODULE:                                                                    
  329. |    modulus.c                                                               
  330. |----------------------------------------------------------------------------|
  331. |                                                                            
  332. |                                                                            
  333. |----------------------------------------------------------------------------|
  334. |1993-09-29/Erik Bachmann                                                    
  335. \---------------------------------------------------------------------------|*/
  336.  
  337. int _CfnTYPE check_modulus11(char *pszBase)
  338. {
  339.    char  szTmp[11] ;
  340.    int   iTmp = 0 ;
  341.  
  342.    /*--------------------*/
  343.  
  344.    strncpy(szTmp, pszBase, strlen(pszBase) - 1) ;
  345.    szTmp[strlen(pszBase) - 1] = '\0' ;
  346.                                        /* Extract base */
  347.    iTmp = pszBase[strlen(pszBase) - 1] - '0' ;
  348.                                        /* Extract current check digit */
  349.  
  350.    if ( modulus11(szTmp) == iTmp )
  351.       return( 0 ) ;                    /* Check digit is OK */
  352.    else
  353.       return( 11 + modulus11(szTmp) ) ;
  354.                                        /* On error return the correct + 11 */
  355. }  /*** check_modulus11() ***/
  356.  
  357.  
  358. /******************************************************/
  359.  
  360. #ifdef   TEST
  361.  
  362. int main(void)
  363. {
  364.    int iStatus ;
  365.  
  366.    /*------------------------------*/
  367.  
  368.    iStatus = modulus11("943457842") ;
  369.    iStatus = check_modulus11("9434578423") ;
  370.    iStatus = modulus10("61248") ;
  371.    iStatus = check_modulus10("612481") ;
  372.  
  373.    return( iStatus ) ;
  374. }
  375. #endif
  376.