1.加密
public static String jiami(String paramBodyJsonStr) { String aeskey = "1234567891234567; String publicKey = 公钥 JSONObject json = new JSONObject(); String priKey = 密钥 String data = null; try { data = AESEncrypt.aesEncrypt(paramBodyJsonStr, aeskey); } catch (Exception e) { e.printStackTrace(); } String key = null; try { key = RSAEncrypt.encode(aeskey, publicKey); } catch (Exception e) { e.printStackTrace(); } // JSONObject json = new JSONObject(); json.put("key", key); json.put("data", data); Log.w("key", key + "data" + data); System.out.println(json.toJSONString()); // return json.toString(); }
2.解密
public static String jiemi(String data, String sign) { JSONObject jsonObject = new JSONObject(); String publicKey = 公钥 String priKey = 密钥 boolean is = RSAEncrypt.doCheck(data, sign, publicKey); String decryptData = ""; String requestBody = null; String key = "b5f8d77c1768e65a"; // if (is){ if (is = true) { // try { // decryptData = RSAEncrypt.decode(key, priKey); // Log.w("解密后key", decryptData); // } catch (Exception e) { // e.printStackTrace(); // } try { requestBody = AESEncrypt.aesDecrypt(data, key); } catch (Exception e) { e.printStackTrace(); } Log.w("验证", is + "" + requestBody); } return requestBody; }
3.AES
public class AESEncrypt { //密钥 (需要前端和后端保持一致) private static final String KEY = "1234567891234567"; //算法 private static final String ALGORITHMSTR = "AES/ECB/PKCS5Padding"; /** * aes解密 * @param encrypt 内容 * @return * @throws Exception */ public static String aesDecrypt(String encrypt) { try { return aesDecrypt(encrypt, KEY); } catch (Exception e) { e.printStackTrace(); return ""; } } /** * aes加密 * @param content * @return * @throws Exception */ public static String aesEncrypt(String content) { try { return aesEncrypt(content, KEY); } catch (Exception e) { e.printStackTrace(); return ""; } } /** * 将byte[]转为各种进制的字符串 * @param bytes byte[] * @param radix 可以转换进制的范围,从Character.MIN_RADIX到Character.MAX_RADIX,超出范围后变为10进制 * @return 转换后的字符串 */ public static String binary(byte[] bytes, int radix){ return new BigInteger(1, bytes).toString(radix);// 这里的1代表正数 } /** * base 64 encode * @param bytes 待编码的byte[] * @return 编码后的base 64 code */ public static String base64Encode(byte[] bytes){ return MyBASE64.encodeBase64String(bytes); } /** * base 64 decode * @param base64Code 待解码的base 64 code * @return 解码后的byte[] * @throws Exception */ public static byte[] base64Decode(String base64Code) throws Exception{ return StringUtils.isEmpty(base64Code) ? null : new BASE64Decoder().decodeBuffer(base64Code); } /** * AES加密 * @param content 待加密的内容 * @param encryptKey 加密密钥 * @return 加密后的byte[] * @throws Exception */ public static byte[] aesEncryptToBytes(String content, String encryptKey) throws Exception { KeyGenerator kgen = KeyGenerator.getInstance("AES"); kgen.init(128); Cipher cipher = Cipher.getInstance(ALGORITHMSTR); cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(encryptKey.getBytes(), "AES")); return cipher.doFinal(content.getBytes("utf-8")); } /** * AES加密为base 64 code * @param content 待加密的内容 * @param encryptKey 加密密钥 * @return 加密后的base 64 code * @throws Exception */ public static String aesEncrypt(String content, String encryptKey) throws Exception { return base64Encode(aesEncryptToBytes(content, encryptKey)); } /** * AES解密 * @param encryptBytes 待解密的byte[] * @param decryptKey 解密密钥 * @return 解密后的String * @throws Exception */ public static String aesDecryptByBytes(byte[] encryptBytes, String decryptKey) throws Exception { KeyGenerator kgen = KeyGenerator.getInstance("AES"); kgen.init(128); Cipher cipher = Cipher.getInstance(ALGORITHMSTR); cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(decryptKey.getBytes(), "AES")); byte[] decryptBytes = cipher.doFinal(encryptBytes); return new String(decryptBytes); } /** * 将base 64 code AES解密 * @param encryptStr 待解密的base 64 code * @param decryptKey 解密密钥 * @return 解密后的string * @throws Exception */ public static String aesDecrypt(String encryptStr, String decryptKey) throws Exception { return StringUtils.isEmpty(encryptStr) ? null : aesDecryptByBytes(base64Decode(encryptStr), decryptKey); } /** * 测试 */ public static void main(String[] args) throws Exception { String content = "a22/lle人在a22/lle人在a22/lle人在a22/lle人在a22/lle人在"; System.out.println("加密前:" + content); System.out.println("加密密钥和解密密钥:" + KEY); String encrypt = aesEncrypt(content, KEY); System.out.println("加密后:" + encrypt); String decrypt = aesDecrypt(encrypt, KEY); System.out.println("解密后:" + decrypt);
4.
public class RSAEncrypt { // private static String KEY_RSA_TYPE = "RSA"; private static String KEY_RSA_TYPE = "RSA"; private static int KEY_SIZE = 512;//JDK方式RSA加密最大只有512位 private static int ENCODE_PART_SIZE = KEY_SIZE/8; public static final String PUBLIC_KEY_NAME = "public"; public static final String PRIVATE_KEY_NAME = "private"; public static final String SIGN_ALGORITHMS = "SHA1WithRSA"; public static void main(String args) throws Exception { // String decStr ="7ezeg0mlm6e"; // Map<String,String> keyPairMap = RSAEncrypt.createRSAKeys(); System.out.println(decStr); String pubKey ="MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAIi3NCFx6VQPvm+lHcAvPUAnD5Y933wGdLlfinpV+ofJQ68rOtaQK4RcFRsn9JZ5f47VnjQajQ4T0c/qcMlVeCECAwEAAQ=="; String priKey = "MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAiLc0IXHpVA++b6UdwC89QCcPlj3ffAZ0uV+KelX6h8lDrys61pArhFwVGyf0lnl/jtWeNBqNDhPRz+pwyVV4IQIDAQABAkBjWg+uRmOzzQUtiSaHpUyztC8lla01KlPk6sNth9Hanp4hOF4jvmQYkE9wGC5s38vRHM71s7Zm0bYnPei2pDeBAiEAxT58+Mx69t53vDhWkx/0Yya8kqTHmRwxeOqFDjnUDakCIQCxcOoeq3yobM4VQ3zhKWJqZWgoPUBrKg33nv26xpBxuQIgI05rKlHX1Oa/ggaHoLBAm5rseEdcnxCH3oAELya0yXkCIQCrPl2z26win18EBm2un1HrfJJYw0Q4KA3yu+4DIz6jgQIhAKoL+5M/yupOGjZ4R1kh5QnJoLD636tQ6Amo4eR8ay6f"; RSAEncrypt.decode("Cjx8FTjkigk4rcKYjAJQJGEvZqxpwkFtzKEnpNIh0pW3oWfhMVs749ocUa0Uoau8csuicuN9rFQ9bbjarmx9/Q==",priKey); String body = "{\"header\":{\"uuid\":\"c619f28aa8a148a9ac8f9070c2bd9b74\",\"deviceHeight\":\"2208\",\"channel\":\"android_mbaidu\",\"clientVersion\":\"0\",\"deviceId\":\"1\",\"deviceType\":\"xiaomi-MI 6X\",\"token\":\"af27a2864dd7775454ce67a6d79a0384\",\"platform\":\"1\",\"systemVersion\":\"12.1\",\"memberId\":\"1014254310217417085\",\"deviceWidth\":\"1242\",\"network\":\"WIFI\",\"appKey\":\"5455f4c3847d506a0be7afb78eb0e618\",\"ip\":\"124.114.56.188\",\"orgId\":\"1008328420328325120\"},\"body\":{}}" ; String aeskey = "1234567891234567" ; String data = AESEncrypt.aesEncrypt(body,aeskey); String key = RSAEncrypt.encode(aeskey, pubKey); JSONObject json = new JSONObject(); json.put("key", key); json.put("data", data); System.out.println(json.toJSONString()); //获取加密的 aesKey String afteraesKey = RSAEncrypt.decode(json.getString("key"), priKey); System.out.println(afteraesKey); String requestBody = AESEncrypt.aesDecrypt(json.getString("data"), afteraesKey); System.out.println(requestBody); } /** * 创建公钥秘钥 * @return */ public static Map<String,String> createRSAKeys(){ Map<String,String> keyPairMap = new HashMap<>();//里面存放公私秘钥的Base64位加密 try { KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_RSA_TYPE); keyPairGenerator.initialize(KEY_SIZE,new SecureRandom()); KeyPair keyPair = keyPairGenerator.generateKeyPair(); //获取公钥秘钥 String publicKeyValue = Base64.encodeToString(keyPair.getPublic().getEncoded(), Base64.NO_WRAP); String privateKeyValue = Base64.encodeToString(keyPair.getPrivate().getEncoded(),Base64.NO_WRAP); System.out.println(publicKeyValue); System.out.println(privateKeyValue); //存入公钥秘钥,以便以后获取 keyPairMap.put(PUBLIC_KEY_NAME,publicKeyValue); keyPairMap.put(PRIVATE_KEY_NAME,privateKeyValue); } catch (NoSuchAlgorithmException e) { // log.error("当前JDK版本没找到RSA加密算法!"); e.printStackTrace(); } return keyPairMap; } /** * 公钥加密 * 描述: * 1字节 = 8位; * 最大加密长度如 1024位私钥时,最大加密长度为 128-11 = 117字节,不管多长数据,加密出来都是 128 字节长度。 * @param sourceStr * @param publicKeyBase64Str * @return */ public static String encode(String sourceStr,String publicKeyBase64Str) throws Exception{ byte [] publicBytes = Base64.decode(publicKeyBase64Str,Base64.NO_WRAP); //公钥加密 X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(publicBytes); List<byte[]> alreadyEncodeListData = new LinkedList<>(); int maxEncodeSize = ENCODE_PART_SIZE - 11; KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec); Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(Cipher.ENCRYPT_MODE,publicKey); byte[] sourceBytes = sourceStr.getBytes("utf-8"); int sourceLen = sourceBytes.length; for(int i=0;i<sourceLen;i+=maxEncodeSize){ int curPosition = sourceLen - i; int tempLen = curPosition; if(curPosition > maxEncodeSize){ tempLen = maxEncodeSize; } byte[] tempBytes = new byte[tempLen];//待加密分段数据 System.arraycopy(sourceBytes,i,tempBytes,0,tempLen); byte[] tempAlreadyEncodeData = cipher.doFinal(tempBytes); alreadyEncodeListData.add(tempAlreadyEncodeData); } int partLen = alreadyEncodeListData.size();//加密次数 int allEncodeLen = partLen * ENCODE_PART_SIZE; byte[] encodeData = new byte[allEncodeLen];//存放所有RSA分段加密数据 for (int i = 0; i < partLen; i++) { byte[] tempByteList = alreadyEncodeListData.get(i); System.arraycopy(tempByteList,0,encodeData,i*ENCODE_PART_SIZE,ENCODE_PART_SIZE); } String encodeBase64Result = Base64.encodeToString(encodeData,Base64.NO_WRAP); return encodeBase64Result; } /** * 私钥解密 * @param sourceBase64RSA * @param privateKeyBase64Str */ public static String decode(String sourceBase64RSA,String privateKeyBase64Str) throws Exception{ byte[] privateBytes = Base64.decode(privateKeyBase64Str,Base64.NO_WRAP); byte[] encodeSource = Base64.decode(sourceBase64RSA,Base64.NO_WRAP); int encodePartLen = encodeSource.length/ENCODE_PART_SIZE; List<byte[]> decodeListData = new LinkedList<>();//所有解密数据 //私钥解密 PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_RSA_TYPE); PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec); Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(Cipher.DECRYPT_MODE,privateKey); int allDecodeByteLen = 0;//初始化所有被解密数据长度 for (int i = 0; i < encodePartLen; i++) { byte[] tempEncodedData = new byte[ENCODE_PART_SIZE]; System.arraycopy(encodeSource,i*ENCODE_PART_SIZE,tempEncodedData,0,ENCODE_PART_SIZE); byte[] decodePartData = cipher.doFinal(tempEncodedData); decodeListData.add(decodePartData); allDecodeByteLen += decodePartData.length; } byte [] decodeResultBytes = new byte[allDecodeByteLen]; for (int i = 0,curPosition = 0; i < encodePartLen; i++) { byte[] tempSorceBytes = decodeListData.get(i); int tempSourceBytesLen = tempSorceBytes.length; System.arraycopy(tempSorceBytes,0,decodeResultBytes,curPosition,tempSourceBytesLen); curPosition += tempSourceBytesLen; } String decodeStrResult = new String(decodeResultBytes,"UTF-8"); return decodeStrResult; } /** * RSA签名 * @param content 待签名数据 * @param privateKey 商户私钥 * @param encode 字符集编码 * @return 签名值 */ public static String sign(String content, String privateKey, String encode) { try { PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec( Base64.decode(privateKey,Base64.NO_WRAP) ); KeyFactory keyf = KeyFactory.getInstance("RSA"); PrivateKey priKey = keyf.generatePrivate(priPKCS8); java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS); signature.initSign(priKey); signature.update( content.getBytes(encode)); byte[] signed = signature.sign(); return Base64.encodeToString(signed,Base64.NO_WRAP); } catch (Exception e) { e.printStackTrace(); } return null; } public static String sign(String content, String privateKey) throws Exception { PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec( Base64.decode(privateKey,Base64.NO_WRAP) ); KeyFactory keyf = KeyFactory.getInstance("RSA"); PrivateKey priKey = keyf.generatePrivate(priPKCS8); java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS); signature.initSign(priKey); signature.update( content.getBytes()); byte[] signed = signature.sign(); return Base64.encodeToString(signed,Base64.NO_WRAP); } /** * RSA验签名检查 * @param content 待签名数据 * @param sign 签名值 * @param publicKey 分配给开发商公钥 * @param encode 字符集编码 * @return 布尔值 */ public static boolean doCheck(String content, String sign, String publicKey,String encode) { try { KeyFactory keyFactory = KeyFactory.getInstance("RSA"); byte[] encodedKey = Base64.decode(publicKey,Base64.NO_WRAP); PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey)); java.security.Signature signature = java.security.Signature .getInstance(SIGN_ALGORITHMS); signature.initVerify(pubKey); signature.update( content.getBytes(encode) ); boolean bverify = signature.verify( Base64.decode(sign,Base64.NO_WRAP) ); return bverify; } catch (Exception e) { e.printStackTrace(); } return false; } public static boolean doCheck(String content, String sign, String publicKey) { try { KeyFactory keyFactory = KeyFactory.getInstance("RSA"); byte[] encodedKey = Base64.decode(publicKey,Base64.NO_WRAP); PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey)); java.security.Signature signature = java.security.Signature .getInstance(SIGN_ALGORITHMS); signature.initVerify(pubKey); signature.update( content.getBytes() ); boolean bverify = signature.verify( Base64.decode(sign,Base64.NO_WRAP) ); return bverify; } catch (Exception e) { e.printStackTrace(); } return false; } }
5.
public class Base64Utils { private static char[] base64EncodeChars = new char[] { '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 byte[] base64DecodeChars = new byte[] { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1 }; /** * 加密 * * @param data * @return */ public static String encode(byte[] data) { StringBuffer sb = new StringBuffer(); int len = data.length; int i = 0; int b1, b2, b3; while (i < len) { b1 = data[i++] & 0xff; if (i == len) { sb.append(base64EncodeChars[b1 >>> 2]); sb.append(base64EncodeChars[(b1 & 0x3) << 4]); sb.append("=="); break; } b2 = data[i++] & 0xff; if (i == len) { sb.append(base64EncodeChars[b1 >>> 2]); sb.append(base64EncodeChars[((b1 & 0x03) << 4) | ((b2 & 0xf0) >>> 4)]); sb.append(base64EncodeChars[(b2 & 0x0f) << 2]); sb.append("="); break; } b3 = data[i++] & 0xff; sb.append(base64EncodeChars[b1 >>> 2]); sb.append(base64EncodeChars[((b1 & 0x03) << 4) | ((b2 & 0xf0) >>> 4)]); sb.append(base64EncodeChars[((b2 & 0x0f) << 2) | ((b3 & 0xc0) >>> 6)]); sb.append(base64EncodeChars[b3 & 0x3f]); } return sb.toString(); } /** * 解密 * * @param str * @return */ public static byte[] decode(String str) { try { return decodePrivate(str); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return new byte[] {}; } private static byte[] decodePrivate(String str) throws UnsupportedEncodingException { StringBuffer sb = new StringBuffer(); byte[] data = null; data = str.getBytes("US-ASCII"); int len = data.length; int i = 0; int b1, b2, b3, b4; while (i < len) { do { b1 = base64DecodeChars[data[i++]]; } while (i < len && b1 == -1); if (b1 == -1) break; do { b2 = base64DecodeChars[data[i++]]; } while (i < len && b2 == -1); if (b2 == -1) break; sb.append((char) ((b1 << 2) | ((b2 & 0x30) >>> 4))); do { b3 = data[i++]; if (b3 == 61) return sb.toString().getBytes("iso8859-1"); b3 = base64DecodeChars[b3]; } while (i < len && b3 == -1); if (b3 == -1) break; sb.append((char) (((b2 & 0x0f) << 4) | ((b3 & 0x3c) >>> 2))); do { b4 = data[i++]; if (b4 == 61) return sb.toString().getBytes("iso8859-1"); b4 = base64DecodeChars[b4]; } while (i < len && b4 == -1); if (b4 == -1) break; sb.append((char) (((b3 & 0x03) << 6) | b4)); } return sb.toString().getBytes("iso8859-1"); } }
6.
public class BASE64Decoder extends CharacterDecoder { /** * This class has 4 bytes per atom */ protected int bytesPerAtom() { return (4); } /** * Any multiple of 4 will do, 72 might be common */ protected int bytesPerLine() { return (72); } /** * 74 * This character array provides the character to value map * 75 * based on RFC1521. * 76 */ private final static char pem_array[] = { // 0 1 2 3 4 5 6 7 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', // 0 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 1 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 2 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', // 3 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', // 4 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', // 5 'w', 'x', 'y', 'z', '0', '1', '2', '3', // 6 '4', '5', '6', '7', '8', '9', '+', '/' // 7 }; private final static byte pem_convert_array[] = new byte[256]; static { for (int i = 0; i < 255; i++) { pem_convert_array[i] = -1; } for (int i = 0; i < pem_array.length; i++) { pem_convert_array[pem_array[i]] = (byte) i; } } byte decode_buffer[] = new byte[4]; /** * 103 * Decode one BASE64 atom into 1, 2, or 3 bytes of data. * 104 */ protected void decodeAtom(PushbackInputStream inStream, OutputStream outStream, int rem) throws java.io.IOException { int i; byte a = -1, b = -1, c = -1, d = -1; if (rem < 2) { throw new CEFormatException("BASE64Decoder: Not enough bytes for an atom."); } do { i = inStream.read(); if (i == -1) { throw new CEStreamExhausted(); } } while (i == '\n' || i == '\r'); decode_buffer[0] = (byte) i; i = readFully(inStream, decode_buffer, 1, rem - 1); if (i == -1) { throw new CEStreamExhausted(); } if (rem > 3 && decode_buffer[3] == '=') { rem = 3; } if (rem > 2 && decode_buffer[2] == '=') { rem = 2; } switch (rem) { case 4: d = pem_convert_array[decode_buffer[3] & 0xff]; // NOBREAK case 3: c = pem_convert_array[decode_buffer[2] & 0xff]; // NOBREAK case 2: b = pem_convert_array[decode_buffer[1] & 0xff]; a = pem_convert_array[decode_buffer[0] & 0xff]; break; } switch (rem) { case 2: outStream.write((byte) (((a << 2) & 0xfc) | ((b >>> 4) & 3))); break; case 3: outStream.write((byte) (((a << 2) & 0xfc) | ((b >>> 4) & 3))); outStream.write((byte) (((b << 4) & 0xf0) | ((c >>> 2) & 0xf))); break; case 4: outStream.write((byte) (((a << 2) & 0xfc) | ((b >>> 4) & 3))); outStream.write((byte) (((b << 4) & 0xf0) | ((c >>> 2) & 0xf))); outStream.write((byte) (((c << 6) & 0xc0) | (d & 0x3f))); break; } return; } }
7.
public class BASE64Encoder extends CharacterEncoder { /** this class encodes three bytes per atom. */ protected int bytesPerAtom() { return (3); } /** * this class encodes 57 bytes per line. This results in a maximum of 57/3 * * 4 or 76 characters per output line. Not counting the line termination. */ protected int bytesPerLine() { return (57); } /** This array maps the characters to their 6 bit values */ private final static char pem_array[] = { // 0 1 2 3 4 5 6 7 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', // 0 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 1 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 2 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', // 3 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', // 4 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', // 5 'w', 'x', 'y', 'z', '0', '1', '2', '3', // 6 '4', '5', '6', '7', '8', '9', '+', '/' // 7 }; /** * encodeAtom - Take three bytes of input and encode it as 4 printable * characters. Note that if the length in len is less than three is encodes * either one or two '=' signs to indicate padding characters. */ protected void encodeAtom(OutputStream outStream, byte data[], int offset, int len) throws IOException { byte a, b, c; if (len == 1) { a = data[offset]; b = 0; c = 0; outStream.write(pem_array[(a >>> 2) & 0x3F]); outStream.write(pem_array[((a << 4) & 0x30) + ((b >>> 4) & 0xf)]); outStream.write('='); outStream.write('='); } else if (len == 2) { a = data[offset]; b = data[offset + 1]; c = 0; outStream.write(pem_array[(a >>> 2) & 0x3F]); outStream.write(pem_array[((a << 4) & 0x30) + ((b >>> 4) & 0xf)]); outStream.write(pem_array[((b << 2) & 0x3c) + ((c >>> 6) & 0x3)]); outStream.write('='); } else { a = data[offset]; b = data[offset + 1]; c = data[offset + 2]; outStream.write(pem_array[(a >>> 2) & 0x3F]); outStream.write(pem_array[((a << 4) & 0x30) + ((b >>> 4) & 0xf)]); outStream.write(pem_array[((b << 2) & 0x3c) + ((c >>> 6) & 0x3)]); outStream.write(pem_array[c & 0x3F]); } } }
8.
public abstract class CharacterEncoder { /** Stream that understands "printing" */ protected PrintStream pStream; /** Return the number of bytes per atom of encoding */ abstract protected int bytesPerAtom(); /** Return the number of bytes that can be encoded per line */ abstract protected int bytesPerLine(); /** * 88 * Encode the prefix for the entire buffer. By default is simply 89 * * opens the PrintStream for use by the other functions. 90 */ protected void encodeBufferPrefix(OutputStream aStream) throws IOException { pStream = new PrintStream(aStream); } /** * 96 * Encode the suffix for the entire buffer. 97 */ protected void encodeBufferSuffix(OutputStream aStream) throws IOException { } /** * 102 * Encode the prefix that starts every output line. 103 */ protected void encodeLinePrefix(OutputStream aStream, int aLength) throws IOException { } /** * 109 * Encode the suffix that ends every output line. By default 110 * * this method just prints a <newline> into the output stream. 111 */ protected void encodeLineSuffix(OutputStream aStream) throws IOException { pStream.println(); } /** Encode one "atom" of information into characters. */ abstract protected void encodeAtom(OutputStream aStream, byte someBytes[], int anOffset, int aLength) throws IOException; /** * 121 * This method works around the bizarre semantics of * BufferedInputStream's 122 * read method. 123 */ protected int readFully(InputStream in, byte buffer[]) throws IOException { for (int i = 0; i < buffer.length; i++) { int q = in.read(); if (q == -1) return i; buffer[i] = (byte) q; } return buffer.length; } /** * 136 * Encode bytes from the input stream, and write them as text * characters 137 * to the output stream. This method will run until it * exhausts the 138 * input stream, but does not print the line suffix for a * final 139 * line that is shorter than bytesPerLine(). 140 */ public void encode(InputStream inStream, OutputStream outStream) throws IOException { int j; int numBytes; byte tmpbuffer[] = new byte[bytesPerLine()]; encodeBufferPrefix(outStream); while (true) { numBytes = readFully(inStream, tmpbuffer); if (numBytes == 0) { break; } encodeLinePrefix(outStream, numBytes); for (j = 0; j < numBytes; j += bytesPerAtom()) { if ((j + bytesPerAtom()) <= numBytes) { encodeAtom(outStream, tmpbuffer, j, bytesPerAtom()); } else { encodeAtom(outStream, tmpbuffer, j, (numBytes) - j); } } if (numBytes < bytesPerLine()) { break; } else { encodeLineSuffix(outStream); } } encodeBufferSuffix(outStream); } /** * 173 * Encode the buffer in <i>aBuffer</i> and write the encoded 174 * * result to the OutputStream <i>aStream</i>. 175 */ public void encode(byte aBuffer[], OutputStream aStream) throws IOException { ByteArrayInputStream inStream = new ByteArrayInputStream(aBuffer); encode(inStream, aStream); } /** * 183 * A 'streamless' version of encode that simply takes a buffer of 184 * * bytes and returns a string containing the encoded buffer. 185 */ public String encode(byte aBuffer[]) { ByteArrayOutputStream outStream = new ByteArrayOutputStream(); ByteArrayInputStream inStream = new ByteArrayInputStream(aBuffer); String retVal = null; try { encode(inStream, outStream); // explicit ascii->unicode conversion retVal = outStream.toString("8859_1"); } catch (Exception IOException) { // This should never happen. throw new Error("CharacterEncoder.encode internal error"); } return (retVal); } /** * 202 * Return a byte array from the remaining bytes in this ByteBuffer. * 203 * * <P> * 204 * The ByteBuffer's position will be advanced to ByteBuffer's limit. * 205 * * <P> * 206 * To avoid an extra copy, the implementation will attempt to return * the 207 * byte array backing the ByteBuffer. If this is not possible, a * 208 * new byte array will be created. 209 */ private byte[] getBytes(ByteBuffer bb) { /* * This should never return a BufferOverflowException, as we're 213 * * careful to allocate just the right amount. 214 */ byte[] buf = null; /* * 218 * If it has a usable backing byte buffer, use it. Use only 219 * * if the array exactly represents the current ByteBuffer. 220 */ if (bb.hasArray()) { byte[] tmp = bb.array(); if ((tmp.length == bb.capacity()) && (tmp.length == bb.remaining())) { buf = tmp; bb.position(bb.limit()); } } if (buf == null) { /* * 232 * This class doesn't have a concept of encode(buf, len, off), * 233 * so if we have a partial buffer, we must reallocate 234 * * space. 235 */ buf = new byte[bb.remaining()]; /* * 239 * position() automatically updated 240 */ bb.get(buf); } return buf; } /** * 248 * Encode the <i>aBuffer</i> ByteBuffer and write the encoded 249 * * result to the OutputStream <i>aStream</i>. 250 * * <P> * 251 * The ByteBuffer's position will be advanced to ByteBuffer's limit. * 252 */ public void encode(ByteBuffer aBuffer, OutputStream aStream) throws IOException { byte[] buf = getBytes(aBuffer); encode(buf, aStream); } /** * 260 * A 'streamless' version of encode that simply takes a ByteBuffer 261 * * and returns a string containing the encoded buffer. 262 * * <P> * 263 * The ByteBuffer's position will be advanced to ByteBuffer's limit. * 264 */ public String encode(ByteBuffer aBuffer) { byte[] buf = getBytes(aBuffer); return encode(buf); } /** * 271 * Encode bytes from the input stream, and write them as text * characters 272 * to the output stream. This method will run until it * exhausts the 273 * input stream. It differs from encode in that it will * add the 274 * line at the end of a final line that is shorter than * bytesPerLine(). 275 */ public void encodeBuffer(InputStream inStream, OutputStream outStream) throws IOException { int j; int numBytes; byte tmpbuffer[] = new byte[bytesPerLine()]; encodeBufferPrefix(outStream); while (true) { numBytes = readFully(inStream, tmpbuffer); if (numBytes == 0) { break; } encodeLinePrefix(outStream, numBytes); for (j = 0; j < numBytes; j += bytesPerAtom()) { if ((j + bytesPerAtom()) <= numBytes) { encodeAtom(outStream, tmpbuffer, j, bytesPerAtom()); } else { encodeAtom(outStream, tmpbuffer, j, (numBytes) - j); } } encodeLineSuffix(outStream); if (numBytes < bytesPerLine()) { break; } } encodeBufferSuffix(outStream); } /** * 306 * Encode the buffer in <i>aBuffer</i> and write the encoded 307 * * result to the OutputStream <i>aStream</i>. 308 */ public void encodeBuffer(byte aBuffer[], OutputStream aStream) throws IOException { ByteArrayInputStream inStream = new ByteArrayInputStream(aBuffer); encodeBuffer(inStream, aStream); } /** * 316 * A 'streamless' version of encode that simply takes a buffer of 317 * * bytes and returns a string containing the encoded buffer. 318 */ public String encodeBuffer(byte aBuffer[]) { ByteArrayOutputStream outStream = new ByteArrayOutputStream(); ByteArrayInputStream inStream = new ByteArrayInputStream(aBuffer); try { encodeBuffer(inStream, outStream); } catch (Exception IOException) { // This should never happen. throw new Error("CharacterEncoder.encodeBuffer internal error"); } return (outStream.toString()); } /** * 332 * Encode the <i>aBuffer</i> ByteBuffer and write the encoded 333 * * result to the OutputStream <i>aStream</i>. 334 * * <P> * 335 * The ByteBuffer's position will be advanced to ByteBuffer's limit. * 336 */ public void encodeBuffer(ByteBuffer aBuffer, OutputStream aStream) throws IOException { byte[] buf = getBytes(aBuffer); encodeBuffer(buf, aStream); } /** * 344 * A 'streamless' version of encode that simply takes a ByteBuffer 345 * * and returns a string containing the encoded buffer. 346 * * <P> * 347 * The ByteBuffer's position will be advanced to ByteBuffer's limit. * 348 */ public String encodeBuffer(ByteBuffer aBuffer) { byte[] buf = getBytes(aBuffer); return encodeBuffer(buf); }
public class CEStreamExhausted extends IOException { }
public class CEFormatException extends IOException { public CEFormatException(String s) { super(s); } }