package net.curisit.securis.utils; import java.math.BigInteger; import java.nio.charset.Charset; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.zip.CRC32; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; public class LicUtils { private static final Logger LOG = LogManager.getLogger(LicUtils.class); public static String md5(String str) { try { MessageDigest mDigest = MessageDigest.getInstance("MD5"); mDigest.update(str.getBytes(DEFAULT_CHARSET), 0, str.length()); BigInteger i = new BigInteger(1, mDigest.digest()); return String.format("%1$032x", i); } catch (NoSuchAlgorithmException e) { LOG.error("Error generating MD5 for string: " + str, e); } return null; } public static String sha256(String str) { return sha256(str.getBytes(DEFAULT_CHARSET)); } public static String sha256(byte[] bytes) { try { MessageDigest mDigest = MessageDigest.getInstance("SHA-256"); mDigest.update(bytes, 0, bytes.length); BigInteger i = new BigInteger(1, mDigest.digest()); return String.format("%1$064x", i); } catch (NoSuchAlgorithmException e) { LOG.error("Error generating SHA-256 for bytes: " + bytes, e); } return null; } public static String sha256(byte[]... bytes) { try { MessageDigest mDigest = MessageDigest.getInstance("SHA-256"); for (byte[] bs : bytes) { mDigest.update(bs, 0, bs.length); } BigInteger i = new BigInteger(1, mDigest.digest()); return String.format("%1$064x", i); } catch (NoSuchAlgorithmException e) { LOG.error("Error generating SHA-256 for bytes: " + bytes, e); } return null; } private final static Charset DEFAULT_CHARSET = Charset.forName("utf-8"); public static String getLicenseCrc(String packCode, String licSufixCode) { CRC32 crc = new CRC32(); crc.update(packCode.getBytes(DEFAULT_CHARSET)); crc.update(licSufixCode.getBytes(DEFAULT_CHARSET)); return String.format("%03d", crc.getValue() % 1000); } public static String getLicenseCrc(String packCode, Integer licSufixCode) { return getLicenseCrc(packCode, licSufixCode.toString()); } public static Integer getLicenseCodeSuffix(String licCode) { String[] parts = splitLicCode(licCode); return new Integer(parts[parts.length - 1]); } public static String getLicenseCode(String packCode, Integer licSufixCode) { String crc = getLicenseCrc(packCode, licSufixCode); return String.format("%s-%s-%s", packCode, crc, licSufixCode); } /** * Check if the license code is valid according to the format, the CRC is * validated * * @param licCode * @return true if license code format and its CRC are valid */ public static boolean checkValidLicenseCodeCrc(String licCode) { String[] parts = splitLicCode(licCode); if (parts == null) { return false; } String crc = getLicenseCrc(parts[0], parts[2]); return crc.equals(parts[1]); } /** * We convert the license code in 3 parts:
* "P1-344-1 = ["P1", "344", "1"]
* "P1-OTHER-344-1 = ["P1-OTHER", "344", "1"]
* "P1-1 = null * * @param code * @return The 2 license code packs or null if code is not valid */ private static String[] splitLicCode(String code) { List separators = new ArrayList<>(); for (int i = 0; i < code.length(); i++) { if (code.charAt(i) == '-') { separators.add(i); } } if (separators.size() < 2) { return null; } int i0 = separators.get(separators.size() - 2); int i1 = separators.get(separators.size() - 1); String[] parts = new String[3]; parts[0] = code.substring(0, i0); parts[1] = code.substring(i0 + 1, i1); parts[2] = code.substring(i1 + 1); return parts; } public static void main(String[] args) { String code = getLicenseCode("PC-K01", 5); System.out.println(code); System.out.println("Is valid ? " + checkValidLicenseCodeCrc(code)); System.out.println("Is valid ? " + Arrays.asList(splitLicCode(code))); } }