1   package kanta;
2   
3   
4   /**
5    * Luokka henkilötunnuksen tarkistamiseksi
6    * @author vesal
7    * @version 9.1.2011
8    *
9    */
10  public class HetuTarkistus  {
11      /** Hetuun kelpaavat tarkistusmerkit järjestyksessä */
12      //                                            0123456789012345678901234567890
13      public static final String TARKISTUSMERKIT = "0123456789ABCDEFHJKLMNPRSTUVWXY";
14  
15      
16      /**
17       * Palauttaa mikä olisi hetun tarkistumerkki. Tuotava parametrinä
18       * laillista muotoa oleva hetu, josta mahdollisesti tarkistumerkki 
19       * puuttuu.
20       * @param hetu tutkittava hetu
21       * @return hetun tarkistusmerkki
22       * @example
23       * <pre name="test">
24       *    hetunTarkistusMerkki("121212-222")    === 'N';
25       *    hetunTarkistusMerkki("121212-222S")   === 'N';
26       *    hetunTarkistusMerkki("121212-222N")   === 'N';
27       *    hetunTarkistusMerkki("121212-231Y")   === 'Y';
28       *    hetunTarkistusMerkki("311212-2317")   === '7';
29       *    hetunTarkistusMerkki("311212-2317XY") === '7'; // vaikka on liikaa merkkejä
30       *    hetunTarkistusMerkki("999999-9999XY") === 'F'; // vaikka on pvm väärin
31       *    hetunTarkistusMerkki("12121A-222S")   === 'N'; #THROWS NumberFormatException
32       *    hetunTarkistusMerkki("12121A-22")     === 'N'; #THROWS StringIndexOutOfBoundsException
33       *    hetunTarkistusMerkki("121")           === 'N'; #THROWS StringIndexOutOfBoundsException
34       * </pre>
35       */
36      public static char hetunTarkistusMerkki(String hetu) {
37          String pvm = hetu.substring(0,6);
38          String yksilo = hetu.substring(7,10);
39          long luku = Long.parseLong(pvm+yksilo);
40          int jakojaannos = (int)(luku % 31L);
41          return TARKISTUSMERKIT.charAt(jakojaannos);
42      }
43      
44     
45      /**
46       * Arvotaan satunnainen kokonaisluku välille [ala,yla]
47       * @param ala arvonnan alaraja
48       * @param yla arvonnan yläraja
49       * @return satunnainen luku väliltä [ala,yla]
50       */
51      public static int rand(int ala, int yla) {
52        double n = (yla-ala)*Math.random() + ala;
53        return (int)Math.round(n);
54      }
55  
56      
57      /**
58       * Arvotaan satunnainen henkilötunnus, joka täyttää hetun ehdot    
59       * @return satunnainen laillinen henkilötunnus
60       */
61      public static String arvoHetu() {
62          String apuhetu = String.format("%02d",rand(1,28))   +
63          String.format("%02d",rand(1,12))   +
64          String.format("%02d",rand(1,99))   + "-" +
65          String.format("%03d",rand(1,1000));
66          return apuhetu + hetunTarkistusMerkki(apuhetu);        
67      }
68      
69  }
70