一、前言
关于JeroMQ的(jeromq-master源码包)中zmq.util.Z85类,对二进制byte[]加解密encode、decode方法,源码说明如下。
二、源码说明
package zmq.util;@b@@b@import java.nio.ByteBuffer;@b@@b@// Z85 codec, taken from 0MQ RFC project, implements RFC32 Z85 encoding@b@public class Z85@b@{@b@ private Z85()@b@ {@b@ }@b@@b@ // Maps base 256 to base 85@b@ private static final String encoder = "0123456789" + "abcdefghij" + "klmnopqrst" + "uvwxyzABCD" + "EFGHIJKLMN"@b@ + "OPQRSTUVWX" + "YZ.-:+=^!/" + "*?&<>()[]{" + "}@%$#";@b@@b@ // Maps base 85 to base 256@b@ // We chop off lower 32 and higher 128 ranges@b@ private static final byte[] decoder = { 0x00, 0x44, 0x00, 0x54, 0x53, 0x52, 0x48, 0x00, 0x4B, 0x4C, 0x46, 0x41,@b@ 0x00, 0x3F, 0x3E, 0x45, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x40, 0x00, 0x49, 0x42,@b@ 0x4A, 0x47, 0x51, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32,@b@ 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x4D, 0x00, 0x4E, 0x43, 0x00, 0x00, 0x0A,@b@ 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C,@b@ 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x4F, 0x00, 0x50, 0x00, 0x00 };@b@@b@ // --------------------------------------------------------------------------@b@ // Encode a binary frame as a string; destination string MUST be at least@b@ // size * 5 / 4 bytes long plus 1 byte for the null terminator. Returns@b@ // dest. Size must be a multiple of 4.@b@ // Returns NULL and sets errno = EINVAL for invalid input.@b@@b@ public static String encode(byte[] data, int size)@b@ {@b@ if (size % 4 != 0) {@b@ return null;@b@ }@b@ StringBuilder builder = new StringBuilder();@b@ int byteNbr = 0;@b@ long value = 0;@b@ while (byteNbr < size) {@b@ // Accumulate value in base 256 (binary)@b@ int d = data[byteNbr++] & 0xff;@b@ if (d < 0) {@b@ System.out.print("");@b@ }@b@ value = value * 256 + d;@b@ if (byteNbr % 4 == 0) {@b@ // Output value in base 85@b@ int divisor = 85 * 85 * 85 * 85;@b@ while (divisor != 0) {@b@ int index = (int) (value / divisor % 85);@b@ if (index < 0) {@b@ System.out.print("");@b@ }@b@ builder.append(encoder.charAt(index));@b@ divisor /= 85;@b@ }@b@ value = 0;@b@ }@b@ }@b@ assert (builder.length() == size * 5 / 4);@b@ return builder.toString();@b@ }@b@@b@ // --------------------------------------------------------------------------@b@ // Decode an encoded string into a binary frame; dest must be at least@b@ // strlen (string) * 4 / 5 bytes long. Returns dest. strlen (string)@b@ // must be a multiple of 5.@b@ // Returns NULL and sets errno = EINVAL for invalid input.@b@@b@ public static byte[] decode(String string)@b@ {@b@ if (string.length() % 5 != 0) {@b@ return null;@b@ }@b@ ByteBuffer buf = ByteBuffer.allocate(string.length() * 4 / 5);@b@@b@ int byteNbr = 0;@b@ int charNbr = 0;@b@ int stringLen = string.length();@b@ long value = 0;@b@ while (charNbr < stringLen) {@b@ // Accumulate value in base 85@b@ value = value * 85 + (decoder[string.charAt(charNbr++) - 32] & 0xff);@b@ if (charNbr % 5 == 0) {@b@ // Output value in base 256@b@ int divisor = 256 * 256 * 256;@b@ while (divisor != 0) {@b@ buf.put(byteNbr++, (byte) ((value / divisor) % 256));@b@ divisor /= 256;@b@ }@b@ value = 0;@b@ }@b@ }@b@ assert (byteNbr == string.length() * 4 / 5);@b@ return buf.array();@b@ }@b@}