其实ByteString没什么好看的。看之前以为有重要内容,看完后发现没有,不过既然已经看了,就记录下来吧。
ByteString封装了以下几点
1、就是把一些输入类型(字符串/字节数组/ByteBuffer/byte)转成字节数组,并封装成新的ByteString返回。
比如ByteString.of(...)
2、封装了对ByteString的比较、加密操作,方便使用
比如ByteString.encode(...)、base64(...)、md5(...)、sha1()、....
ByteString.startWith(...)、endWith(...)
差不多就这些东西。
public class ByteString implements Serializable, Comparable<ByteString> { static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; /** A singleton empty {@code ByteString}. */ public static final ByteString EMPTY = ByteString.of(); final byte[] data; transient int hashCode; // Lazily computed; 0 if unknown. transient String utf8; // Lazily computed. ByteString(byte[] data) { this.data = data; // Trusted internal constructor doesn't clone data. } /** * Returns a new byte string containing a clone of the bytes of {@code data}. */ public static ByteString of(byte... data) { if (data == null) { throw new IllegalArgumentException("data == null"); } return new ByteString(data.clone()); } //复制data的缓存中byteCount个字节的内容到新的byte[],返回一个新的ByteString public static ByteString of(byte[] data, int offset, int byteCount) { if (data == null) { throw new IllegalArgumentException("data == null"); } checkOffsetAndCount(data.length, offset, byteCount);//校验参数 byte[] copy = new byte[byteCount]; System.arraycopy(data, offset, copy, 0, byteCount); return new ByteString(copy); } //复制data的缓存中0-data.remaining()的内容到copy数组,返回新的ByteString public static ByteString of(ByteBuffer data) { if (data == null) { throw new IllegalArgumentException("data == null"); } byte[] copy = new byte[data.remaining()];// data.get(copy); return new ByteString(copy); } //把string转byte[]存入新建的ByteString返回,byteString.utf8保存了string的原字符串 public static ByteString encodeUtf8(String s) { if (s == null) { throw new IllegalArgumentException("s == null"); } ByteString byteString = new ByteString(s.getBytes(Util.UTF_8)); byteString.utf8 = s; return byteString; } /** Returns a new byte string containing the {@code charset}-encoded bytes of {@code s}. */ public static ByteString encodeString(String s, Charset charset) { if (s == null) { throw new IllegalArgumentException("s == null"); } if (charset == null) { throw new IllegalArgumentException("charset == null"); } return new ByteString(s.getBytes(charset)); } //获取data[]对应的UTF8字符串 public String utf8() { String result = utf8; // We don't care if we double-allocate in racy code. return result != null ? result : (utf8 = new String(data, Util.UTF_8)); } //把data[]转成charset的字符串 public String string(Charset charset) { if (charset == null) { throw new IllegalArgumentException("charset == null"); } return new String(data, charset); } //把data[]用Base64编码后返回 public String base64() { return Base64.encode(data); } //把data[]用md5加密后返回 public ByteString md5() { return digest("MD5"); } //把data[]用sha1加密后返回 public ByteString sha1() { return digest("SHA-1"); } //把data用sha256加密后返回 public ByteString sha256() { return digest("SHA-256"); } //把data用sha512加密后返回 public ByteString sha512() { return digest("SHA-512"); } //加密的api private ByteString digest(String algorithm) { try { return ByteString.of(MessageDigest.getInstance(algorithm).digest(data)); } catch (NoSuchAlgorithmException e) { throw new AssertionError(e); } } /** Returns the 160-bit SHA-1 HMAC of this byte string. */ public ByteString hmacSha1(ByteString key) { return hmac("HmacSHA1", key); } /** Returns the 256-bit SHA-256 HMAC of this byte string. */ public ByteString hmacSha256(ByteString key) { return hmac("HmacSHA256", key); } /** Returns the 512-bit SHA-512 HMAC of this byte string. */ public ByteString hmacSha512(ByteString key) { return hmac("HmacSHA512", key); } private ByteString hmac(String algorithm, ByteString key) { try { Mac mac = Mac.getInstance(algorithm); mac.init(new SecretKeySpec(key.toByteArray(), algorithm)); return ByteString.of(mac.doFinal(data)); } catch (NoSuchAlgorithmException e) { throw new AssertionError(e); } catch (InvalidKeyException e) { throw new IllegalArgumentException(e); } } //如果data是url的字节数组,用Base64对该url的字节数组编码,返回编码后的字符串 public String base64Url() { return Base64.encodeUrl(data); } /** * Decodes the Base64-encoded bytes and returns their value as a byte string. * Returns null if {@code base64} is not a Base64-encoded sequence of bytes. */ public static @Nullable ByteString decodeBase64(String base64) { if (base64 == null) { throw new IllegalArgumentException("base64 == null"); } byte[] decoded = Base64.decode(base64); return decoded != null ? new ByteString(decoded) : null; } /** Returns this byte string encoded in hexadecimal. */ public String hex() { char[] result = new char[data.length * 2]; int c = 0; for (byte b : data) { result[c++] = HEX_DIGITS[(b >> 4) & 0xf]; result[c++] = HEX_DIGITS[b & 0xf]; } return new String(result); } /** Decodes the hex-encoded bytes and returns their value a byte string. */ public static ByteString decodeHex(String hex) { if (hex == null) { throw new IllegalArgumentException("hex == null"); } if (hex.length() % 2 != 0) { throw new IllegalArgumentException("Unexpected hex string: " + hex); } byte[] result = new byte[hex.length() / 2]; for (int i = 0; i < result.length; i++) { int d1 = decodeHexDigit(hex.charAt(i * 2)) << 4; int d2 = decodeHexDigit(hex.charAt(i * 2 + 1)); result[i] = (byte) (d1 + d2); } return of(result); } private static int decodeHexDigit(char c) { if (c >= '0' && c <= '9') { return c - '0'; } if (c >= 'a' && c <= 'f') { return c - 'a' + 10; } if (c >= 'A' && c <= 'F') { return c - 'A' + 10; } throw new IllegalArgumentException("Unexpected hex digit: " + c); } //把输入流in的内容写入字节数组,封装成ByteString返回 public static ByteString read(InputStream in, int byteCount) throws IOException { if (in == null) { throw new IllegalArgumentException("in == null"); } if (byteCount < 0) { throw new IllegalArgumentException("byteCount < 0: " + byteCount); } byte[] result = new byte[byteCount]; for (int offset = 0, read; offset < byteCount; offset += read) { read = in.read(result, offset, byteCount - offset); if (read == -1) { throw new EOFException(); } } return new ByteString(result); } //把data[]中A-Z之间的字符大写转小写,生成新的字节数组,封装成新的ByteString返回 public ByteString toAsciiLowercase() { for (int i = 0; i < data.length; i++) { byte c = data[i]; if (c < 'A' || c > 'Z') { continue; } byte[] lowercase = data.clone(); lowercase[i++] = (byte) (c - ('A' - 'a')); for (; i < lowercase.length; i++) { c = lowercase[i]; if (c < 'A' || c > 'Z') { continue; } lowercase[i] = (byte) (c - ('A' - 'a')); } return new ByteString(lowercase); } return this; } //把data[]中a-z之间的字符,小写转大写,生成新的字节数组,封装成新的ByteString后返回 public ByteString toAsciiUppercase() { for (int i = 0; i < data.length; i++) { byte c = data[i]; if (c < 'a' || c > 'z') { continue; } byte[] lowercase = data.clone(); lowercase[i++] = (byte) (c - ('a' - 'A')); for (; i < lowercase.length; i++) { c = lowercase[i]; if (c < 'a' || c > 'z') { continue; } lowercase[i] = (byte) (c - ('a' - 'A')); } return new ByteString(lowercase); } return this; } /** * Returns a byte string that is a substring of this byte string, beginning at the specified * index until the end of this string. Returns this byte string if {@code beginIndex} is 0. */ public ByteString substring(int beginIndex) { return substring(beginIndex, data.length); } //把data[]中beginIndex到endIndex之间的内容封装成新的字节数组,封装成ByteStirng返回 public ByteString substring(int beginIndex, int endIndex) { if (beginIndex < 0) { throw new IllegalArgumentException("beginIndex < 0"); } if (endIndex > data.length) { throw new IllegalArgumentException("endIndex > length(" + data.length + ")"); } int subLen = endIndex - beginIndex; if (subLen < 0) { throw new IllegalArgumentException("endIndex < beginIndex"); } if ((beginIndex == 0) && (endIndex == data.length)) { return this; } byte[] copy = new byte[subLen]; System.arraycopy(data, beginIndex, copy, 0, subLen); return new ByteString(copy); } //返回data[]第pos个字节 public byte getByte(int pos) { return data[pos]; } //返回ByteString中data[]的长度 public int size() { return data.length; } //返回data[]的一个副本 public byte[] toByteArray() { return data.clone(); } //返回data[]本身 byte[] internalArray() { return data; } //用data[]封装成一个只读的ByteBuffer视图返回 public ByteBuffer asByteBuffer() { return ByteBuffer.wrap(data).asReadOnlyBuffer(); } //把当前data[]中的内容写入out输出流中 public void write(OutputStream out) throws IOException { if (out == null) { throw new IllegalArgumentException("out == null"); } out.write(data); } //把data[]中内容写入buffer中 void write(Buffer buffer) { buffer.write(data, 0, data.length); } //比较当前ByteString.data[]的offset~offset+byteCount的内容与otherOffset.data[]的otherOffset~otherOffset+byteCount的内容 public boolean rangeEquals(int offset, ByteString other, int otherOffset, int byteCount) { return other.rangeEquals(otherOffset, this.data, offset, byteCount); } /** * Returns true if the bytes of this in {@code [offset..offset+byteCount)} equal the bytes of * {@code other} in {@code [otherOffset..otherOffset+byteCount)}. Returns false if either range is * out of bounds. */ public boolean rangeEquals(int offset, byte[] other, int otherOffset, int byteCount) { return offset >= 0 && offset <= data.length - byteCount && otherOffset >= 0 && otherOffset <= other.length - byteCount && arrayRangeEquals(data, offset, other, otherOffset, byteCount); } //判断当前bytestring.data[]前缀 public final boolean startsWith(ByteString prefix) { return rangeEquals(0, prefix, 0, prefix.size()); } public final boolean startsWith(byte[] prefix) { return rangeEquals(0, prefix, 0, prefix.length); } //判断当前bytestring.data[]后缀 public final boolean endsWith(ByteString suffix) { return rangeEquals(size() - suffix.size(), suffix, 0, suffix.size()); } public final boolean endsWith(byte[] suffix) { return rangeEquals(size() - suffix.length, suffix, 0, suffix.length); } //判断other在当前ByteString所处的位置索引 public final int indexOf(ByteString other) { return indexOf(other.internalArray(), 0); } ... @Override public int compareTo(ByteString byteString) { int sizeA = size(); int sizeB = byteString.size(); for (int i = 0, size = Math.min(sizeA, sizeB); i < size; i++) { int byteA = getByte(i) & 0xff;//&0xff,防止java类型转换补码导致数据发生变化 int byteB = byteString.getByte(i) & 0xff; if (byteA == byteB) { continue; } return byteA < byteB ? -1 : 1; } if (sizeA == sizeB) { return 0; } return sizeA < sizeB ? -1 : 1; } ... }