Java tutorial
package com.fortinet.qcdb; import java.security.MessageDigest; import java.util.regex.Pattern; import org.apache.commons.codec.binary.Base32; /** * * @author Colin Cheng */ public class AscenLinkKey { private String do_md5(String sn, String func, int argc, String[] argv) { try { MessageDigest m = MessageDigest.getInstance("MD5"); m.update("DEMO_TTL".getBytes()); m.update(sn.getBytes()); m.update("*%#($a3EB".getBytes()); m.update(func.getBytes()); for (int i = 0; i < argc; i++) m.update(argv[i].getBytes()); Base32 b32 = new Base32(); byte[] k = b32.encode(m.digest()); StringBuilder sb = new StringBuilder(); for (int i = 0; i < 25; i++) { if (i > 0 && i % 5 == 0) sb.append("-"); sb.append((char) k[i]); } return sb.toString(); } catch (Exception e) { e.printStackTrace(); return null; } } private String b32encode_TR_L7BM(byte[] digest) { char[] tab32 = { '2', 'Z', '3', 'Y', 'P', 'X', '5', 'W', '6', 'V', '7', 'U', '8', 'T', '9', 'S', 'A', 'G', 'Q', 'C', 'E', 'R', 'J', 'F', 'D', 'L', 'M', 'B', 'N', 'K', 'H', '4' }; int srclen = 16; int[] src = new int[srclen]; for (int i = 0; i < digest.length && i < srclen; i++) { // src[i] = String.valueOf(digest[i]).codePointAt(0); src[i] = digest[i] & 0xff; } StringBuilder sb = new StringBuilder(); int i = 0; for (i = 0; i < srclen - 5; i += 5) { sb.append(tab32[src[i] >> 3 & 0x1f]); sb.append(tab32[(((src[i] << 5 & 0xff) >> 3) | (src[i + 1] >> 6)) & 0x1f]); sb.append(tab32[(src[i + 1] << 2 & 0xff) >> 3 & 0x1f]); sb.append(tab32[(((src[i + 1] << 7 & 0xff) >> 3) | (src[i + 2] >> 4)) & 0x1f]); sb.append(tab32[((src[i + 2] << 4 & 0xff) >> 3 | (src[i + 3] >> 7)) & 0x1f]); sb.append(tab32[(src[i + 3] << 1 & 0xff) >> 3 & 0x1f]); sb.append(tab32[((src[i + 3] << 6 & 0xff) >> 3 | (src[i + 4] >> 5)) & 0x1f]); sb.append(tab32[(src[i + 4] << 3 & 0xff) >> 3 & 0x1f]); } sb.append(tab32[src[i] >> 3 & 0x1f]); sb.append(tab32[(src[i] << 5 & 0xff) >> 3]); return sb.toString(); } private String do_md5_TR_L7BM(String sn, String func) { try { String seed = "dkru4shelob" + sn + func; MessageDigest m = MessageDigest.getInstance("MD5"); m.update(seed.getBytes()); StringBuilder k = new StringBuilder(b32encode_TR_L7BM(m.digest())); for (int i = 24; i > 0; i -= 4) { k.insert(i, '-'); } return k.toString(); } catch (Exception e) { e.printStackTrace(); return null; } } private int check_snv(String[] argv) { Pattern patt = Pattern.compile("^[0-9a-fA-F]{2}(-[0-9a-fA-F]{2}){5}$"); if (argv.length < 1 || !patt.matcher(argv[0]).matches()) return -1; return 1; } private int check_sa(String[] argv) { if (argv.length < 2) return -1; if ("normal".equals(argv[1])) return 2; if ("demo".equals(argv[1]) && argv.length >= 3) return 3; return -1; } private int check_mc(String[] argv) { if (argv.length < 4 || (!"normal".equals(argv[1]) && !"demo".equals(argv[1]))) return -1; if ("normal".equals(argv[3])) return 4; if ("demo".equals(argv[3]) && argv.length >= 5) return 5; return -1; } private int check_fu(String[] argv) { if (argv.length < 1) return -1; return 1; } private int check_tr(String[] argv) { return 0; } private int check_l7bm(String[] argv) { return 0; } public enum LicenseType { TR, Layer7BM, serialnum, system, model, firmware_update; public String key() { if (firmware_update == this) { return "firmware-update"; } return this.name(); } } private String errMsg = ""; public String getError() { return this.errMsg; } public String gen_key(String sn, LicenseType fkey, String[] argv) { return gen_key(sn, fkey, argv, 0); } public String gen_key(String sn, LicenseType fkey, String[] argv, int demo_num) { if (sn == null || (sn = sn.trim()).isEmpty()) { errMsg = "No serial number"; return null; } Pattern patt = Pattern.compile("^[0-9A-Z]{4}(-[0-9A-Z]{4}){3}$"); if (!patt.matcher(sn).matches()) { errMsg = "Invalid serial number"; return null; } int argc = 0; switch (fkey) { case TR: case Layer7BM: if (demo_num > 0) return this.do_md5_TR_L7BM(sn, fkey.key() + demo_num); return this.do_md5_TR_L7BM(sn, fkey.key()); case serialnum: argc = check_snv(argv); break; case system: argc = check_sa(argv); break; case model: argc = check_mc(argv); break; case firmware_update: argc = check_fu(argv); break; } if (0 > argc) { errMsg = "Invalid argument"; return null; } return this.do_md5(sn, fkey.key(), argc, argv); } public static void main(String[] args) { // String sn = "ABCD-F234-EFGH-234A"; // String sn = "1111-2222-3333-4444"; String sn = "M4U5-FXK5-3VOZ-HW7T"; // LicenseType ltype = LicenseType.system; // LicenseType ltype = LicenseType.Layer7BM; // LicenseType ltype = LicenseType.TR; LicenseType ltype = LicenseType.model; // LicenseType ltype = LicenseType.firmware_update; // LicenseType ltype = LicenseType.serialnum; // String[] argv = {"ts", "demo", "1", "2", "7"}; // String[] argv = {"00-22-44-66-88-AA"}; // String[] argv = {"706", "normal"}; String[] argv = { "700", "demo", "702", "normal" }; // String[] argv = {"6.4"}; AscenLinkKey alk = new AscenLinkKey(); String license_key = alk.gen_key(sn, ltype, argv); if (license_key == null) { System.out.println(alk.getError()); } else { System.out.println(license_key); } if (ltype == LicenseType.TR || ltype == LicenseType.Layer7BM) { int DEMO_KEYS = 10; System.out.println("Demo Licence keys:"); for (int i = 1; i <= DEMO_KEYS; i++) { System.out.println(alk.gen_key(sn, ltype, argv, i)); } } } }