package com.jiuqi.mobile.nigo.comeclose.utils; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.CharacterCodingException; import java.nio.charset.Charset; import java.nio.charset.CharsetEncoder; import java.nio.charset.CodingErrorAction; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.UUID; /** * UUID 作为主键与数据库原GUID二进制数组匹配工具类 * @author modi * */ public final class GUIDUtils { /** * 获得空UUID * @return */ public static UUID getEmptyUUID(){ return new UUID(0, 0); } /** * @Title: getUUIDByText * @Description: 根据text消息获取uuid * @param @param text * @param @return 设定文件 * @return UUID 返回类型 * @throws */ public static UUID getUUIDByText(String text){ return md5s.get().digest(text); } private static class MD5Digest { private static Charset UTF8 = Charset.forName("UTF-8"); private final MessageDigest md5; private final CharsetEncoder encoder; final UUID digest(CharSequence message) { if (message == null) { throw new IllegalArgumentException("message is null"); } if (message.length() == 0) { return getEmptyUUID(); } final ByteBuffer bb; try { bb = this.encoder.encode(CharBuffer.wrap(message)); } catch (CharacterCodingException e) { // UnsafeString.unsafe.throwException(e); return null;// 永远不会到这里 } this.md5.update(bb); return getUUID(this.md5.digest()); } // final byte[] digestTo16Bytes(CharSequence message) { // if (message == null) { // throw new IllegalArgumentException("message is null"); // } // if (message.length() == 0) { // return new byte[16]; // } // final ByteBuffer bb; // try { // bb = this.encoder.encode(CharBuffer.wrap(message)); // } catch (CharacterCodingException e) { //// UnsafeString.unsafe.throwException(e); // return null;// 永远不会到这里 // } // this.md5.update(bb); // return this.md5.digest(); // } // // final long digestToLong(CharSequence message) { // if (message == null) { // throw new IllegalArgumentException("message is null"); // } // if (message.length() == 0) { // return 0; // } // try { // this.md5.update(this.encoder.encode(CharBuffer.wrap(message))); // } catch (CharacterCodingException e) { //// UnsafeString.unsafe.throwException(e); // return 0; // } // final byte[] buf = this.md5.digest(); // long msb = buf[0] & 0xff; // for (int i = 1; i < 8; i++) { // msb = (msb << 8) | (buf[i] & 0xff); // // } // return msb; // } MD5Digest() { MessageDigest md5; try { md5 = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException e) { md5 = null; } this.md5 = md5; this.encoder = UTF8.newEncoder(); this.encoder.onMalformedInput(CodingErrorAction.IGNORE); this.encoder.onUnmappableCharacter(CodingErrorAction.IGNORE); } } private static ThreadLocal<MD5Digest> md5s = new ThreadLocal<MD5Digest>() { @Override protected MD5Digest initialValue() { return new MD5Digest(); }; }; /** * 通过二进制数组获得UUID * @param bytes * @return */ public static UUID getUUID(byte[] bytes){ if (bytes == null) { return null; } int length = bytes.length; if (length == 0) { return getEmptyUUID(); } int c = length > 8 ? 8 : length; int index = 0; long msb = bytes[index++] & 0xff; while (index < c) { msb = (msb << 8) | (bytes[index++] & 0xff); } long lsb; if (index < length) { lsb = bytes[index++] & 0xff; while (index < length) { lsb = (lsb << 8) | (bytes[index++] & 0xff); } } else { lsb = 0; } return new UUID(msb, lsb); } /** * 通过UUID获得二进制数组 * @param id * @return */ @Deprecated public static byte[] getBytes(UUID id){ byte[] bytes = new byte[16]; long sb = id.getLeastSignificantBits(); for (int i = 15; i >= 8; i--) { bytes[i] = (byte) sb; sb >>>= 8; } sb = id.getMostSignificantBits(); for (int i = 7; i >= 0; i--) { bytes[i] = (byte) sb; sb >>>= 8; } return bytes; } /** * 通过UUID获得二进制数组 * @param uuid * @return */ @Deprecated public static byte[] getBytes(String uuid){ return getBytes(UUID.fromString(uuid)); } /** * 不推荐使用方法,过度时期使用 * GUID字符串转换为UUID * @param str 为GUID字符串,不可用UUID字符串 * @return */ @Deprecated public static UUID valueOf(String str){ if (str == null) { return null; } int strl = str.length(); if (strl == 32) { return valueOf(hexToLong(str, 0), hexToLong(str, 16)); }else if(str.contains("-")){ return UUID.fromString(str); } return null; } /** * @Title: hexToLong * @Description: 十六进制转为long型 * @param @param str * @param @param start * @param @return 设定文件 * @return long 返回类型 * @throws */ private static long hexToLong(String str, int start) { long temp = parseChar(str, start++); temp = temp << 4 | parseChar(str, start++); temp = temp << 4 | parseChar(str, start++); temp = temp << 4 | parseChar(str, start++); temp = temp << 4 | parseChar(str, start++); temp = temp << 4 | parseChar(str, start++); temp = temp << 4 | parseChar(str, start++); temp = temp << 4 | parseChar(str, start++); temp = temp << 4 | parseChar(str, start++); temp = temp << 4 | parseChar(str, start++); temp = temp << 4 | parseChar(str, start++); temp = temp << 4 | parseChar(str, start++); temp = temp << 4 | parseChar(str, start++); temp = temp << 4 | parseChar(str, start++); temp = temp << 4 | parseChar(str, start++); return temp << 4 | parseChar(str, start++); } private final static int h2b_A_10 = 'A' - 10; private final static int h2b_a_10 = 'a' - 10; private static int parseChar(String s, int offset) throws StringIndexOutOfBoundsException { char c = s.charAt(offset); if (c < '0') { } else if (c <= '9') { return c - '0'; } else if (c < 'A') { } else if (c <= 'F') { return c - h2b_A_10; } else if (c < 'a') { } else if (c <= 'f') { return c - h2b_a_10; } throw new StringIndexOutOfBoundsException("在偏移量" + offset + "处出现无效的十六进制字符'" + c + "'"); } /** * 根据两个long创建ID * @param mostSigBits 高位 * @param leastSigBits 地位 * @return 返回ID */ public static UUID valueOf(final long mostSigBits, final long leastSigBits) { if (mostSigBits == 0 && leastSigBits == 0) { return getEmptyUUID(); } return new UUID(mostSigBits, leastSigBits); } /** * @Title: toGUIDString * @Description: uuid转为String * @param @param id * @param @return 设定文件 * @return String 返回类型 * @throws */ public static String toGUIDString(UUID id){ boolean withPrefix = false, upperCase = true; int j = withPrefix ? 34 : 32; char[] hex = new char[j]; if (withPrefix) { hex[0] = '0'; hex[1] = upperCase ? 'X' : 'x'; } long sb = id.getLeastSignificantBits(); j -= 2; byteToHex(hex, j, (byte) sb, upperCase); j -= 2; sb >>>= 8; byteToHex(hex, j, (byte) sb, upperCase); j -= 2; sb >>>= 8; byteToHex(hex, j, (byte) sb, upperCase); j -= 2; sb >>>= 8; byteToHex(hex, j, (byte) sb, upperCase); j -= 2; sb >>>= 8; byteToHex(hex, j, (byte) sb, upperCase); j -= 2; sb >>>= 8; byteToHex(hex, j, (byte) sb, upperCase); j -= 2; sb >>>= 8; byteToHex(hex, j, (byte) sb, upperCase); j -= 2; sb >>>= 8; byteToHex(hex, j, (byte) sb, upperCase); j -= 2; sb = id.getMostSignificantBits(); byteToHex(hex, j, (byte) sb, upperCase); j -= 2; sb >>>= 8; byteToHex(hex, j, (byte) sb, upperCase); j -= 2; sb >>>= 8; byteToHex(hex, j, (byte) sb, upperCase); j -= 2; sb >>>= 8; byteToHex(hex, j, (byte) sb, upperCase); j -= 2; sb >>>= 8; byteToHex(hex, j, (byte) sb, upperCase); j -= 2; sb >>>= 8; byteToHex(hex, j, (byte) sb, upperCase); j -= 2; sb >>>= 8; byteToHex(hex, j, (byte) sb, upperCase); j -= 2; sb >>>= 8; byteToHex(hex, j, (byte) sb, upperCase); int charCount = hex.length; if (charCount == 0) { return ""; } return new String(hex); } /** * @Title: byteToHex * @Description: 二进制转为十六进制 * @param @param hex * @param @param index * @param @param b * @param @param upperCase 设定文件 * @return void 返回类型 * @throws */ private static void byteToHex(char[] hex, int index, byte b,boolean upperCase) { int h = b >>> 4 & 0xF; if (upperCase) { hex[index] = (char) (h > 9 ? h + h2b_A_10 : h + '0'); h = b & 0xF; hex[index + 1] = (char) (h > 9 ? h + h2b_A_10 : h + '0'); } else { hex[index] = (char) (h > 9 ? h + h2b_a_10 : h + '0'); h = b & 0xF; hex[index + 1] = (char) (h > 9 ? h + h2b_a_10 : h + '0'); } } public static void main(String[] args) { System.out.println(GUIDUtils.getEmptyUUID()); System.out.println(GUIDUtils.toGUIDString(GUIDUtils.getEmptyUUID())); } }