Base64、MD5、RSA和ASE加密算法总结及JAVA实现-Base64

匿名 (未验证) 提交于 2019-12-02 21:53:52

常见的加密算法可以分成三类,对称加密算法,非对称加密算法和Hash算法。

Base64

BASE64并不能算为一种加密算法,而是一种编码方式,通常用于把二进制数据编码为可写的字符形式的数据。BASE64是一种可逆的编码方式。
它通常用作存储、传输一些二进制数据编码方法!也是MIME(多用途互联网邮件扩展,主要用作电子邮件标准)中一种可打印字符表示二进制数据的常见编码方法!

  1. 首先将待编码的内容转换成8位二进制,每3个字符为一组;
  2. 如果编码前的长度是3n+1,编码后的内容最后面补上2个 ‘=’,如果编码前的长度是3n+2,编码后的内容最后面补上1个 ‘=’。
  3. 再将每一组的二进制内容拆分成6位的二进制,不足6位的后面补足0;
  4. 每个6进制的数字前面补足0,保证变成8位二进制;
  5. 将补足后的内容根据base64编码表转换成base64内容输出;
    /**      * 编码类      */     public static class Encoder {         private final byte[] newline;         private final int linemax;         private final boolean isURL;         private final boolean doPadding;          private Encoder(boolean isURL, byte[] newline, int linemax, boolean doPadding) {             this.isURL = isURL;             this.newline = newline;             this.linemax = linemax;             this.doPadding = doPadding;         }         private static final char[] toBase64 = {                 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',                 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',                 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',                 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',                 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'         };         private static final char[] toBase64URL = {                 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',                 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',                 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',                 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',                 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_'         }         private final int outLength(int srclen) {             int len = 0;             if (doPadding) {                 len = 4 * ((srclen + 2) / 3);             } else {                 int n = srclen % 3;                 len = 4 * (srclen / 3) + (n == 0 ? 0 : n + 1);             }             if (linemax > 0)                                  // line separators                 len += (len - 1) / linemax * newline.length;             return len;         }          /**          * 编码          * @param src          * @return          */         public byte[] encode(byte[] src) {             int len = outLength(src.length);          // dst array size             byte[] dst = new byte[len];             int ret = encode0(src, 0, src.length, dst);             if (ret != dst.length)                 return Arrays.copyOf(dst, ret);             return dst;         }         /**          * 编码          * @param src          * @return          */         public String encodeToString(byte[] src) {             byte[] encoded = encode(src);             return new String(encoded, 0, encoded.length);         }         private int encode0(byte[] src, int off, int end, byte[] dst) {             char[] base64 = isURL ? toBase64URL : toBase64;             int sp = off;             int slen = (end - off) / 3 * 3;             int sl = off + slen;             if (linemax > 0 && slen  > linemax / 4 * 3)                 slen = linemax / 4 * 3;             int dp = 0;             while (sp < sl) {                 int sl0 = Math.min(sp + slen, sl);                 for (int sp0 = sp, dp0 = dp ; sp0 < sl0; ) {                     int bits = (src[sp0++] & 0xff) << 16 |                             (src[sp0++] & 0xff) <<  8 |                             (src[sp0++] & 0xff);                     dst[dp0++] = (byte)base64[(bits >>> 18) & 0x3f];                     dst[dp0++] = (byte)base64[(bits >>> 12) & 0x3f];                     dst[dp0++] = (byte)base64[(bits >>> 6)  & 0x3f];                     dst[dp0++] = (byte)base64[bits & 0x3f];                 }                 int dlen = (sl0 - sp) / 3 * 4;                 dp += dlen;                 sp = sl0;                 if (dlen == linemax && sp < end) {                     for (byte b : newline){                         dst[dp++] = b;                     }                 }             }             if (sp < end) {               // 1 or 2 leftover bytes                 int b0 = src[sp++] & 0xff;                 dst[dp++] = (byte)base64[b0 >> 2];                 if (sp == end) {                     dst[dp++] = (byte)base64[(b0 << 4) & 0x3f];                     if (doPadding) {                         dst[dp++] = '=';                         dst[dp++] = '=';                     }                 } else {                     int b1 = src[sp++] & 0xff;                     dst[dp++] = (byte)base64[(b0 << 4) & 0x3f | (b1 >> 4)];                     dst[dp++] = (byte)base64[(b1 << 2) & 0x3f];                     if (doPadding) {                         dst[dp++] = '=';                     }                 }             }             return dp;         }     }     /**      * 解码类      */     public static class Decoder {          private final boolean isURL;         private final boolean isMIME;         private Decoder(boolean isURL, boolean isMIME) {             this.isURL = isURL;             this.isMIME = isMIME;         }          private static final int[] fromBase64 = new int[256];         static {             Arrays.fill(fromBase64, -1);             for (int i = 0; i < Encoder.toBase64.length; i++)                 fromBase64[Encoder.toBase64[i]] = i;             fromBase64['='] = -2;         }         private static final int[] fromBase64URL = new int[256];          static {             Arrays.fill(fromBase64URL, -1);             for (int i = 0; i < Encoder.toBase64URL.length; i++)                 fromBase64URL[Encoder.toBase64URL[i]] = i;             fromBase64URL['='] = -2;         }         /**          * 解码          * @param src          * @return          */         public byte[] decode(byte[] src) {             byte[] dst = new byte[outLength(src, 0, src.length)];             int ret = decode0(src, 0, src.length, dst);             if (ret != dst.length) {                 dst = Arrays.copyOf(dst, ret);             }             return dst;         }         /**          * 解码          * @param src          * @return          */         public byte[] decode(String src) {             return decode(src.getBytes(StandardCharsets.ISO_8859_1));         }         private int outLength(byte[] src, int sp, int sl) {             int[] base64 = isURL ? fromBase64URL : fromBase64;             int paddings = 0;             int len = sl - sp;             if (len == 0)                 return 0;             if (len < 2) {                 if (isMIME && base64[0] == -1)                     return 0;                 throw new IllegalArgumentException(                         "Input byte[] should at least have 2 bytes for base64 bytes");             }             if (isMIME) {                 // scan all bytes to fill out all non-alphabet. a performance                 // trade-off of pre-scan or Arrays.copyOf                 int n = 0;                 while (sp < sl) {                     int b = src[sp++] & 0xff;                     if (b == '=') {                         len -= (sl - sp + 1);                         break;                     }                     if ((b = base64[b]) == -1)                         n++;                 }                 len -= n;             } else {                 if (src[sl - 1] == '=') {                     paddings++;                     if (src[sl - 2] == '=')                         paddings++;                 }             }             if (paddings == 0 && (len & 0x3) !=  0)                 paddings = 4 - (len & 0x3);             return 3 * ((len + 3) / 4) - paddings;         }         private int decode0(byte[] src, int sp, int sl, byte[] dst) {             int[] base64 = isURL ? fromBase64URL : fromBase64;             int dp = 0;             int bits = 0;             int shiftto = 18;       // pos of first byte of 4-byte atom             while (sp < sl) {                 int b = src[sp++] & 0xff;                 if ((b = base64[b]) < 0) {                     if (b == -2) {         // padding byte '='                         // =     shiftto==18 unnecessary padding                         // x=    shiftto==12 a dangling single x                         // x     to be handled together with non-padding case                         // xx=   shiftto==6&&sp==sl missing last =                         // xx=y  shiftto==6 last is not =                         if (shiftto == 6 && (sp == sl || src[sp++] != '=') ||                                 shiftto == 18) {                             throw new IllegalArgumentException(                                     "Input byte array has wrong 4-byte ending unit");                         }                         break;                     }                     if (isMIME)    // skip if for rfc2045                         continue;                     else                         throw new IllegalArgumentException(                                 "Illegal base64 character " +                                         Integer.toString(src[sp - 1], 16));                 }                 bits |= (b << shiftto);                 shiftto -= 6;                 if (shiftto < 0) {                     dst[dp++] = (byte)(bits >> 16);                     dst[dp++] = (byte)(bits >>  8);                     dst[dp++] = (byte)(bits);                     shiftto = 18;                     bits = 0;                 }             }             // reached end of byte array or hit padding '=' characters.             if (shiftto == 6) {                 dst[dp++] = (byte)(bits >> 16);             } else if (shiftto == 0) {                 dst[dp++] = (byte)(bits >> 16);                 dst[dp++] = (byte)(bits >>  8);             } else if (shiftto == 12) {                 // dangling single "x", incorrectly encoded.                 throw new IllegalArgumentException(                         "Last unit does not have enough valid bits");             }             // anything left is invalid, if is not MIME.             // if MIME, ignore all non-base64 character             while (sp < sl) {                 if (isMIME && base64[src[sp++]] < 0)                     continue;                 throw new IllegalArgumentException(                         "Input byte array has incorrect ending byte at " + sp);             }             return dp;         }     }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!