はじめに
* Java で、シリアル番号生成を考えていたら、以下のサイトを見つけたので参考にして実装してみるhttp://www.venishjoe.net/2009/08/basic-serial-key-generation-module-in.html
参考:シリアル番号に関わるトラブル
http://www.barcode-net.com/chisiki/serial_number.htmlhttp://takahitokikuchi.poitan.net/2012/11/03/%E3%83%91%E3%82%B9%E3%83%AF%E3%83%BC%E3%83%89%E3%82%84%E3%82%B7%E3%83%AA%E3%82%A2%E3%83%AB%E7%95%AA%E5%8F%B7%EF%BC%88%E3%82%B7%E3%83%AA%E3%82%A2%E3%83%AB%E3%82%B3%E3%83%BC%E3%83%89%EF%BC%89%E3%81%AE/
* 以下の文字が紛らわしく間違うトラブルがあるとかないとか... + 数字の「0(ゼロ)」と英字の「O(オー)」 + 数字の「1(イチ)」と英字の「l(エル)」or「I(アイ)」 + 数字の「8(ハチ)」と英字の「B(ビー)」 => カタカナで振り仮名振るなどの対策が必要かも... ※そのプログラムを書いてみた。以下の関連記事を参照のこと。http://blogs.yahoo.co.jp/dk521123/36586289.html
サンプル
import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class Main { private static final String DELIMITTER = "-"; public static void main(String[] args) throws NoSuchAlgorithmException { String input = "1234567890123456789012345678901234567890"; String serialNumber = createSerialNumber(input); System.out.println("SN : " + serialNumber + " Valid? " + isValidSerialNumber(serialNumber, input)); System.out.println("SN : f71sX-6ec5e-f68s5-b4d00 Valid? " + isValidSerialNumber("f71sX-6ec5e-f68s5-b4d00", input)); System.out.println("+++++++++++++++++++++++++++++++++++"); String input2 = "526252"; serialNumber = createSerialNumber(input, input2); System.out.println("SN : " + serialNumber + " Valid? " + isValidSerialNumber(serialNumber, input, input2)); System.out.println("SN : f71sX-6ec5e-f68s5-b4d00 Valid? " + isValidSerialNumber("f71sX-6ec5e-f68s5-b4d00", input, input2)); } private static String createSerialNumber(String... sourceValues) throws NoSuchAlgorithmException { try { String sourceValue = ""; for (String value : sourceValues) { sourceValue = sourceValue + value; } String serialNumberEncodedForMd5 = calculateSecurityHash(sourceValue, "MD5"); sourceValue = sourceValue + serialNumberEncodedForMd5; String serialNumberEncodedForSha1 = calculateSecurityHash(sourceValue, "SHA1"); sourceValue = sourceValue + serialNumberEncodedForSha1; String serialNumberEncodedForMd2 = calculateSecurityHash(sourceValue, "MD2"); String serialNumberEncoded = serialNumberEncodedForMd2 + serialNumberEncodedForMd5 + serialNumberEncodedForSha1; StringBuilder serialNumber = new StringBuilder(); serialNumber.append(serialNumberEncoded.charAt(12)); serialNumber.append(serialNumberEncoded.charAt(101)); serialNumber.append(serialNumberEncoded.charAt(23)); serialNumber.append(serialNumberEncoded.charAt(97)); serialNumber.append(serialNumberEncoded.charAt(79)); serialNumber.append(DELIMITTER); serialNumber.append(serialNumberEncoded.charAt(76)); serialNumber.append(serialNumberEncoded.charAt(1)); serialNumber.append(serialNumberEncoded.charAt(21)); serialNumber.append(serialNumberEncoded.charAt(3)); serialNumber.append(serialNumberEncoded.charAt(43)); serialNumber.append(DELIMITTER); serialNumber.append(serialNumberEncoded.charAt(11)); serialNumber.append(serialNumberEncoded.charAt(46)); serialNumber.append(serialNumberEncoded.charAt(35)); serialNumber.append(serialNumberEncoded.charAt(9)); serialNumber.append(serialNumberEncoded.charAt(81)); serialNumber.append(DELIMITTER); serialNumber.append(serialNumberEncoded.charAt(39)); serialNumber.append(serialNumberEncoded.charAt(94)); serialNumber.append(serialNumberEncoded.charAt(54)); serialNumber.append(serialNumberEncoded.charAt(25)); serialNumber.append(serialNumberEncoded.charAt(44)); return serialNumber.toString(); } catch (NoSuchAlgorithmException ex) { ex.printStackTrace(); throw ex; } } private static boolean isValidSerialNumber(String serialNumber, String... sourceValues) throws NoSuchAlgorithmException { String sourceSerialNumber = createSerialNumber(sourceValues); return sourceSerialNumber.equals(serialNumber); } private static String calculateSecurityHash(String targetValue, String algorithm) throws java.security.NoSuchAlgorithmException { byte[] targetValueBytes = targetValue.getBytes(); MessageDigest messageDigest = MessageDigest.getInstance(algorithm); messageDigest.update(targetValueBytes); byte[] messageDigestBytes = messageDigest.digest(); return DatatypeConverter.printHexBinary(messageDigestBytes); } }
出力結果
SN : 93a60-c2682-b6f52-8d0fa Valid? true SN : f71sX-6ec5e-f68s5-b4d00 Valid? false +++++++++++++++++++++++++++++++++++ SN : 58977-8c422-5bf07-48e96 Valid? true SN : f71sX-6ec5e-f68s5-b4d00 Valid? false