教学服务系统

 找回密码
 立即注册
搜索
查看: 814|回复: 3

信息计算2019级1班17号刘帆杰

[复制链接]

9

主题

16

帖子

117

积分

注册会员

Rank: 2

积分
117
发表于 2022-5-30 19:48:01 | 显示全部楼层 |阅读模式
本帖最后由 刘帆杰 于 2022-5-30 19:49 编辑

rsa算法原理
RSA算法产生密钥的过程: 1.系统产生两个大素数p, q(保密) 2.计算n=pq(公开),欧拉函数Φ(n)=(p-1)(q-1)(保密) 3.随机选择满足gcd(e,Φ(n))=1e作为公钥(公开),加密密钥就是(e,n) 4.计算满足ed=1(mod Φ(n))d作为私钥(保密),解密密钥即为(d,n) RSA的加解密过程: 首先将明文分组并数字化,每个数字化分组明文的长度不大于log n,然后对每个明文分组m依次进行加解密运算: 1.加密运算:使用公钥e和要加密的明文m进行c=me(mod n)运算即得密文 2.解密运算:使用私钥d和要加密的明文m进行c=md(mod n)运算即得明文。
代码
  1. package com.密码算法;

  2. import java.io.UnsupportedEncodingException;
  3. import java.math.BigInteger;
  4. import java.util.Random;
  5. import java.util.Scanner;

  6. public class RSA4 {
  7.     private static BigInteger n;// = p * q,两个大质数的乘积
  8.     private static BigInteger n2;// = p * q,两个大质数的乘积
  9.     private static BigInteger e;// 加密公钥指数
  10.     private static BigInteger e2;// 签名公钥指数
  11.     private static BigInteger d;// 加密私钥指数
  12.     private static BigInteger b;// 签名私钥指数,签名公钥和加密公钥相同
  13.     private final int PQMINLENGTH = 1024;// p、q最小的长度(比特数)
  14.     private static final BigInteger ZERO = BigInteger.ZERO;
  15.     private static final BigInteger ONE = BigInteger.ONE;
  16.     private static final BigInteger TWO = new BigInteger("2");
  17.     private static final int ERR_VAL = 100;

  18.     public static void main(String[] args) throws RSA4.pqException, UnsupportedEncodingException {
  19.         Scanner input = new Scanner(System.in);
  20.         int pqLength = 1024;// p、q长度(比特数)
  21.         System.out.println("请输入要加密的内容:");
  22.         String originalText = input.nextLine();
  23.         RSA4 rsa = new RSA4(pqLength);
  24.         System.out.println("加密前:" + originalText);
  25.         BigInteger[] c2 = rsa.encryption(originalText, b, n2);// 签名
  26.         System.out.print("加签后:");
  27.         for (int i = 0; i < c2.length; i++) {
  28.             System.out.println(c2[i]);
  29.         }
  30.         String tmp = rsa.decryption(c2, e2, n2);
  31.         System.out.println("解签后:" + tmp);// 解密
  32.         if (originalText.equals(tmp)) {
  33.             System.out.println("签名验证成功");
  34.             BigInteger[] c = rsa.encryption(originalText, e, n);// 加密
  35.             System.out.print("加密后:");
  36.             for (int i = 0; i < c.length; i++) {
  37.                 System.out.println(c[i]);
  38.             }
  39.             System.out.println("解密后:" + rsa.decryption(c, d, n));// 解密
  40.         } else System.out.println("签名验证失败");
  41.     }

  42.     private class pqException extends Exception {
  43.         private static final long serialVersionUID = -7777566816579144864L;

  44.         public pqException(String message) {
  45.             super(message);
  46.         }
  47.     }

  48.     public RSA4(int pqLength) throws RSA4.pqException {
  49.         generateKey(pqLength);// 产生密钥
  50.     }

  51.     //密钥产生。
  52.     private void generateKey(int pqLength) throws RSA4.pqException {
  53.         BigInteger p = BigInteger.ZERO;// 两个大素数用于加密
  54.         BigInteger q = BigInteger.ZERO;
  55.         BigInteger p2 = BigInteger.ZERO;// 两个大素数用于签名
  56.         BigInteger q2 = BigInteger.ZERO;
  57.         BigInteger φn;// = (p-1)(q-1)
  58.         BigInteger φn2;// = (p2-1)(q2-1)

  59.         if (pqLength < PQMINLENGTH) {
  60.             throw new pqException("p、q长度小于" + PQMINLENGTH + ",请重新选择更大的比特数!");
  61.         }
  62.         p = RSA4.generateNBitRandomPrime(pqLength);
  63.         q = RSA4.generateNBitRandomPrime(pqLength);

  64.         p2 = RSA4.generateNBitRandomPrime(pqLength);
  65.         q2 = RSA4.generateNBitRandomPrime(pqLength);

  66.         n = p.multiply(q);
  67.         n2 = p2.multiply(q2);

  68.         System.out.println("随机产生四个素数p、q、p2、q2");
  69.         System.out.println("p:" + p);
  70.         System.out.println("q:" + q);
  71.         System.out.println("p2:" + p2);
  72.         System.out.println("q2:" + q2);
  73.         System.out.println("p、q乘积为n:" + n);
  74.         System.out.println("p2、q2乘积为n2:" + n2);
  75.         φn = (p.subtract(BigInteger.ONE)).multiply(q.subtract(BigInteger.ONE));
  76.         φn2 = (p2.subtract(BigInteger.ONE)).multiply(q2.subtract(BigInteger.ONE));

  77.         //随机产生公钥
  78.         int numDigits;
  79.         try {
  80.             numDigits = Integer.parseInt("15");
  81.         } catch (Exception e1) {
  82.             numDigits = 128;
  83.         }

  84.         BigInteger start = bigRandom(numDigits);
  85.         BigInteger start2 = bigRandom(numDigits);
  86.         BigInteger big = nextPrime(start);
  87.         BigInteger big2 = nextPrime(start2);
  88.         e = big;
  89.         e2 = big2;
  90.         while (e.compareTo(φn) == 1 || fun(e, φn)) {
  91.             System.out.println("e不合要求,请重新产生" + (e.compareTo(φn) == 1)
  92.                     + fun(e, φn));
  93.             try {
  94.                 numDigits = Integer.parseInt("15");
  95.             } catch (Exception e1) {
  96.                 numDigits = 128;
  97.             }
  98.             start = bigRandom(numDigits);
  99.             big = nextPrime(start);
  100.             e = big;
  101.         }
  102.         while (e2.compareTo(φn2) == 1 || fun(e2, φn2)) {
  103.             System.out.println("e2不合要求,请重新产生" + (e2.compareTo(φn2) == 1)
  104.                     + fun(e2, φn2));
  105.             try {
  106.                 numDigits = Integer.parseInt("15");
  107.             } catch (Exception e1) {
  108.                 numDigits = 128;
  109.             }
  110.             start = bigRandom(numDigits);
  111.             big = nextPrime(start);
  112.             e2 = big;
  113.         }

  114.         d = RSA4.extdGcd(e, φn)[1];// 利用扩展欧几里得算法求私钥d
  115.         b = RSA4.extdGcd(e2, φn2)[1];// 利用扩展欧几里得算法求私钥b
  116.         if (d.compareTo(BigInteger.ZERO) != 1) {// 私钥不可以小于0
  117.             d = d.add(φn);
  118.         }
  119.         if (b.compareTo(BigInteger.ZERO) != 1) {// 私钥不可以小于0
  120.             b = b.add(φn2);
  121.         }
  122.         System.out.println("加密公钥为:" + e);
  123.         System.out.println("签名公钥为:" + e2);
  124.         System.out.println("加密私钥为:" + d);
  125.         System.out.println("签名私钥为:" + b);
  126.     }

  127.     //RSA加密。
  128.     private BigInteger[] encryption(String plainText, BigInteger e, BigInteger n) throws UnsupportedEncodingException {
  129.         String textNum = "";// 明文数字字符串表示形式
  130.         BigInteger m = BigInteger.ZERO;// 明文数字表示形式
  131.         byte[] textByte = plainText.getBytes("UTF-8");
  132.         for (int i = 0; i < textByte.length; i++) {// 每个字节用3位数的整数表示,不够则在前面补0
  133.             int bn = textByte[i] & 0xff;
  134.             if (bn < 10) {
  135.                 textNum += "00" + bn;
  136.             } else if (bn < 100) {
  137.                 textNum += "0" + bn;
  138.             } else {
  139.                 textNum += bn;
  140.             }
  141.         }
  142.         m = new BigInteger(textNum);

  143.         BigInteger[] mArray = null;// 明文分组结果
  144.         if (m.compareTo(n) == -1) {// m < n,可直接加密
  145.             mArray = new BigInteger[1];
  146.             mArray[0] = m;
  147.         } else {
  148.             int groupLength = n.toString().length() - 1;// 每组明文长度
  149.             int mStringLength = m.toString().length();// 明文转化为字符串的长度
  150.             while (groupLength % 3 != 0) {// 由于前面每个字节用3位整数表示,因此每组的长度必须为3的整数,避免恢复时错误
  151.                 groupLength--;
  152.             }
  153.             if (mStringLength % groupLength != 0) {// 如果最后一组的长度不足
  154.                 mArray = new BigInteger[mStringLength / groupLength + 1];
  155.             } else {
  156.                 mArray = new BigInteger[mStringLength / groupLength];
  157.             }

  158.             String tmp;
  159.             for (int i = 0; i < mArray.length; i++) {
  160.                 tmp = "";
  161.                 if (i != mArray.length - 1) {// 根据每组长度进行分割分组保存
  162.                     tmp = textNum.substring(groupLength * i, groupLength * i + groupLength);
  163.                 } else {
  164.                     tmp = textNum.substring(groupLength * i);
  165.                 }
  166.                 mArray[i] = new BigInteger(tmp);
  167.             }
  168.         }

  169.         for (int i = 0; i < mArray.length; i++) {// 逐组加密并返回
  170.             mArray[i] = expMod(mArray[i], e, n);
  171.         }
  172.         return mArray;
  173.     }


复制代码


回复

使用道具 举报

9

主题

16

帖子

117

积分

注册会员

Rank: 2

积分
117
 楼主| 发表于 2022-5-30 19:48:57 | 显示全部楼层
本帖最后由 刘帆杰 于 2022-5-30 19:50 编辑
  1. //RSA解密。
  2.     private String decryption(BigInteger[] c, BigInteger d, BigInteger n) {
  3.         String cPadding = "";
  4.         String mToString = "";
  5.         int mToStringLengthMod = 0;
  6.         BigInteger m = BigInteger.ZERO;
  7.         for (int i = 0; i < c.length; i++) {// 逐组解密
  8.             m = RSA4.expMod(c[i], d, n);
  9.             mToString = m.toString();
  10.             mToStringLengthMod = m.toString().length() % 3;
  11.             if (mToStringLengthMod != 0) {// 由于加密时String转BigInter时前者前面的0并不会计入,所以需要确认并补全
  12.                 for (int j = 0; j < 3 - mToStringLengthMod; j++) {
  13.                     mToString = "0" + mToString;
  14.                 }
  15.             }
  16.             cPadding += mToString;
  17.         }

  18.         int byteNum = cPadding.length() / 3;// 明文总字节数
  19.         byte[] result = new byte[byteNum];
  20.         for (int i = 0; i < byteNum; i++) {// 每三位数转化为byte型并返回该byte数组所表达的字符串
  21.             result[i] = (byte) (Integer.parseInt(cPadding.substring(i * 3, i * 3 + 3)));
  22.         }
  23.         return new String(result);
  24.     }


  25.     //利用扩展欧几里得算法求出私钥d,使得de = kφ(n)+1,k为整数。
  26.     private static BigInteger[] extdGcd(BigInteger e, BigInteger φn) {
  27.         BigInteger[] gdk = new BigInteger[3];

  28.         if (φn.compareTo(BigInteger.ZERO) == 0) {
  29.             gdk[0] = e;
  30.             gdk[1] = BigInteger.ONE;
  31.             gdk[2] = BigInteger.ZERO;
  32.             return gdk;
  33.         } else {
  34.             gdk = extdGcd(φn, e.remainder(φn));
  35.             BigInteger tmp_k = gdk[2];
  36.             gdk[2] = gdk[1].subtract(e.divide(φn).multiply(gdk[2]));
  37.             gdk[1] = tmp_k;
  38.             return gdk;
  39.         }
  40.     }

  41.     // 利用米勒·罗宾算法判断一个数是否是质数。
  42.     private static boolean isPrime(BigInteger p) {
  43.         if (p.compareTo(BigInteger.TWO) == -1) {// 小于2直接返回false
  44.             return false;
  45.         }
  46.         if ((p.compareTo(BigInteger.TWO) != 0) && (p.remainder(BigInteger.TWO).compareTo(BigInteger.ZERO) == 0)) {// 不等于2且是偶数直接返回false
  47.             return false;
  48.         }

  49.         BigInteger p_1 = p.subtract(BigInteger.ONE);
  50.         BigInteger m = p_1;// 找到q和m使得p = 1 + 2^q * m
  51.         int q = m.getLowestSetBit();// 二进制下从右往左返回第一次出现1的索引
  52.         m = m.shiftRight(q);

  53.         for (int i = 0; i < 5; i++) {// 判断的轮数,精度、轮数和时间三者之间成正比关系
  54.             BigInteger b;
  55.             do {// 在区间1~p上生成均匀随机数
  56.                 b = new BigInteger(String.valueOf(p.bitLength()));
  57.             } while (b.compareTo(BigInteger.ONE) <= 0 || b.compareTo(p) >= 0);

  58.             int j = 0;
  59.             BigInteger z = RSA4.expMod(b, m, p);
  60.             while (!((j == 0 && z.equals(BigInteger.ONE)) || z.equals(p_1))) {
  61.                 if ((j > 0 && z.equals(BigInteger.ONE)) || ++j == q) {
  62.                     return false;
  63.                 }
  64.                 z = RSA4.expMod(z, BigInteger.TWO, p);
  65.             }
  66.         }

  67.         return true;
  68.     }

  69.     private static BigInteger generateNBitRandomPrime(int n) {
  70.         BigInteger tmp = new BigInteger("2").pow(n - 1);// 最高位肯定是1
  71.         BigInteger result = new BigInteger("2").pow(n - 1);
  72.         Random random = new Random();
  73.         int r1 = random.nextInt(101);// 产生0-100的整数,用于确定0和1的比例
  74.         int r2;

  75.         while (true) {// 循环产生数,直到该数为素数
  76.             for (int i = n - 2; i >= 0; i--) {// 逐位产生表示数的0和1,并根据所在位计算结果相加起来
  77.                 r2 = random.nextInt(101);
  78.                 if (0 < r2 && r2 < r1) {// 产生的数为1
  79.                     result = result.add(BigInteger.TWO.pow(i));
  80.                 }
  81.                 continue;
  82.             }

  83.             if (RSA4.isPrime(result)) {// 素数判断
  84.                 return result;
  85.             }

  86.             result = tmp;// 重新计算
  87.         }
  88.     }

  89.     //蒙哥马利快速幂模运算,返回base^exponent mod module的结果。
  90.     private static BigInteger expMod(BigInteger base, BigInteger exponent, BigInteger module) {
  91.         BigInteger result = BigInteger.ONE;
  92.         BigInteger tmp = base.mod(module);

  93.         while (exponent.compareTo(BigInteger.ZERO) != 0) {
  94.             if ((exponent.and(BigInteger.ONE).compareTo(BigInteger.ZERO)) != 0) {
  95.                 result = result.multiply(tmp).mod(module);
  96.             }
  97.             tmp = tmp.multiply(tmp).mod(module);
  98.             exponent = exponent.shiftRight(1);
  99.         }
  100.         return result;
  101.     }

  102.     //判断是否互素
  103.     public static boolean fun(BigInteger x, BigInteger y) {
  104.         BigInteger t;
  105.         while (!(y.equals(new BigInteger("0")))) {
  106.             t = x;
  107.             x = y;
  108.             y = t.mod(y);
  109.         }
  110.         if (x.equals(new BigInteger("1")))
  111.             return false;
  112.         else
  113.             return true;
  114.     }

  115.     public BigInteger bigRandom(int numDigits) {
  116.         // 产生一个随机大整数,各位上的数字都是随机产生的,首位不为 0
  117.         StringBuffer s = new StringBuffer("");
  118.         for (int i = 0; i < numDigits; i++)
  119.             if (i == 0)
  120.                 s.append(randomDigit(false));
  121.             else
  122.                 s.append(randomDigit(true));
  123.         return (new BigInteger(s.toString()));
  124.     }

  125.     private StringBuffer randomDigit(boolean isZeroOK) {
  126.         // 产生一个随机的数字(字符串形式的),isZeroOK 决定这个数字是否可以为 0
  127.         int index;
  128.         if (isZeroOK)
  129.             index = (int) Math.floor(Math.random() * 10);
  130.         else
  131.             index = 1 + (int) Math.floor(Math.random() * 9);
  132.         return (digits[index]);
  133.     }

  134.     private static StringBuffer[] digits = {
  135.             new StringBuffer("0"),
  136.             new StringBuffer("1"), new StringBuffer("2"),
  137.             new StringBuffer("3"), new StringBuffer("4"),
  138.             new StringBuffer("5"), new StringBuffer("6"),
  139.             new StringBuffer("7"), new StringBuffer("8"), new StringBuffer("9")};

  140.     public BigInteger nextPrime(BigInteger start) {
  141.         if (isEven(start))
  142.             start = start.add(ONE);
  143.         else
  144.             start = start.add(TWO);
  145.         if (start.isProbablePrime(ERR_VAL))
  146.             return (start);
  147.         else
  148.             return (nextPrime(start));
  149.     }

  150.     private static boolean isEven(BigInteger n) {
  151.         // 测试一个大整数是否为偶数
  152.         return (n.mod(TWO).equals(ZERO));
  153.     }
  154. }
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

9

主题

16

帖子

117

积分

注册会员

Rank: 2

积分
117
 楼主| 发表于 2022-5-30 20:02:28 | 显示全部楼层
本帖最后由 刘帆杰 于 2022-5-30 20:03 编辑

ECC算法
原理:ECC加密算法是一种公钥加密技术,以椭圆曲线理论为基础。利用有限域上椭圆曲线的点构成的Abel群离散对数难解性,实现加密、解密和数字签名。将椭圆曲线中的加法运算与离散对数中的模乘运算相对应,就可以建立基于椭圆曲线的对应密码体制。
代码:
  1. package com.example.test;

  2. import javax.crypto.Cipher;
  3. import javax.crypto.NullCipher;
  4. import java.io.*;
  5. import java.security.*;
  6. import java.security.interfaces.ECPrivateKey;
  7. import java.security.interfaces.ECPublicKey;
  8. import java.security.spec.PKCS8EncodedKeySpec;
  9. import java.security.spec.X509EncodedKeySpec;
  10. import java.util.HashMap;
  11. import java.util.Map;

  12. public class ECC {
  13.     public static void main(String[] args) throws Exception {
  14.         Map<String,String> map = GenerateKey.getGenerateKey();
  15.         String privKey = map.get(ECCEnum.PRIVATE_KEY.value());
  16.         String pubKey = map.get(ECCEnum.PUBLIC_KEY.value());

  17.         System.out.println("私钥:" + privKey);
  18.         System.out.println("公钥:" + pubKey);
  19.         String text = "aslkdjlwkjdlaskjdlaskjdlakjwdlkawjdJkasldjals卢卡斯的积分";
  20.         byte [] b = ECCUtil.encrypt(text.getBytes("UTF-8"),pubKey);
  21.         String str = BASE64Encoder.encodeBuffer(b);
  22.         System.out.println("密文:" + str);
  23.         String outputStr = new String(ECCUtil.decrypt(b,privKey));
  24.         System.out.println("原始文本:" + text);
  25.         System.out.println("解密文本:" + outputStr);
  26.     }
  27. }

  28. enum ECCEnum {

  29.     ALGORITHM("EC"),
  30.     PROVIDER("BC"),
  31.     PUBLIC_KEY("PUBLIC_KEY"),
  32.     PRIVATE_KEY("PRIVATE_KEY");



  33.     private String value;

  34.     ECCEnum(String value) {
  35.         this.value = value;
  36.     }

  37.     public String value() {
  38.         return this.value;
  39.     }
  40. }



  41. class ECCUtil implements Serializable {
  42.     public static byte[] encrypt(byte[] data, String publicKey)
  43.             throws Exception {
  44.         byte[] keyBytes = BASE64Decoder.decodeBuffer(publicKey);

  45.         X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
  46.         KeyFactory keyFactory = KeyFactory.getInstance(ECCEnum.ALGORITHM.value());

  47.         ECPublicKey pubKey = (ECPublicKey) keyFactory
  48.                 .generatePublic(x509KeySpec);

  49.         Cipher cipher = new NullCipher();
  50.         cipher.init(Cipher.ENCRYPT_MODE, pubKey);
  51.         return cipher.doFinal(data);
  52.     }

  53.     public static byte[] decrypt(byte[] data, String privateKey) throws Exception {
  54.         byte[] keyBytes = BASE64Decoder.decodeBuffer(privateKey);

  55.         PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
  56.         KeyFactory keyFactory = KeyFactory.getInstance(ECCEnum.ALGORITHM.value());

  57.         ECPrivateKey priKey = (ECPrivateKey) keyFactory
  58.                 .generatePrivate(pkcs8KeySpec);

  59.         Cipher cipher = new NullCipher();
  60.         cipher.init(Cipher.DECRYPT_MODE, priKey);

  61.         return cipher.doFinal(data);
  62.     }
  63. }


  64. class GenerateKey implements Serializable {

  65.     static {
  66.         Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
  67.     }

  68.     public static Map<String,String> getGenerateKey() throws NoSuchProviderException, NoSuchAlgorithmException {
  69.         KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ECCEnum.ALGORITHM.value(),
  70.                 ECCEnum.PROVIDER.value());
  71.         keyPairGenerator.initialize(256, new SecureRandom());
  72.         KeyPair kp = keyPairGenerator.generateKeyPair();
  73.         ECPublicKey publicKey = (ECPublicKey) kp.getPublic();
  74.         ECPrivateKey privateKey = (ECPrivateKey) kp.getPrivate();
  75.         Map<String,String> map = new HashMap<>();

  76.         map.put(ECCEnum.PRIVATE_KEY.value(), BASE64Encoder.encodeBuffer(privateKey.getEncoded()));
  77.         map.put(ECCEnum.PUBLIC_KEY.value(), BASE64Encoder.encodeBuffer(publicKey.getEncoded()));
  78.         return map;
  79.     }
  80. }

复制代码


回复

使用道具 举报

9

主题

16

帖子

117

积分

注册会员

Rank: 2

积分
117
 楼主| 发表于 2022-5-30 20:02:57 | 显示全部楼层
刘帆杰 发表于 2022-5-30 20:02
ECC算法
原理:ECC加密算法是一种公钥加密技术,以椭圆曲线理论为基础。利用有限域上椭圆曲线的点构成的A ...
  1. class BASE64Decoder extends FilterInputStream {
  2. private static final char[] chars = {
  3. 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
  4. 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
  5. 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
  6. 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
  7. 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
  8. 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
  9. '8', '9', '+', '/'
  10. };

  11. private static final int[] ints = new int[128];
  12. static {
  13. for (int i = 0; i < 64; i++) {
  14. ints[chars[i]] = i;
  15. }
  16. }

  17. private int charCount;
  18. private int carryOver;


  19. public BASE64Decoder(InputStream in) {
  20. super(in);
  21. }


  22. public int read() throws IOException {
  23. int x;
  24. do {
  25. x = in.read();
  26. if (x == -1) {
  27. return -1;
  28. }
  29. } while (Character.isWhitespace((char)x));
  30. charCount++;

  31. if (x == '=') {
  32. return -1;
  33. }

  34. x = ints[x];

  35. int mode = (charCount - 1) % 4;

  36. if (mode == 0) {
  37. carryOver = x & 63;
  38. return read();
  39. }

  40. else if (mode == 1) {
  41. int decoded = ((carryOver << 2) + (x >> 4)) & 255;
  42. carryOver = x & 15;
  43. return decoded;
  44. }
  45. else if (mode == 2) {
  46. int decoded = ((carryOver << 4) + (x >> 2)) & 255;
  47. carryOver = x & 3;
  48. return decoded;
  49. }
  50. else if (mode == 3) {
  51. int decoded = ((carryOver << 6) + x) & 255;
  52. return decoded;
  53. }
  54. return -1;
  55. }


  56. public int read(byte[] buf, int off, int len) throws IOException {
  57. if (buf.length < (len + off - 1)) {
  58. throw new IOException("The input buffer is too small: " + len +
  59. " bytes requested starting at offset " + off + " while the buffer " +
  60. " is only " + buf.length + " bytes long.");
  61. }

  62. int i;
  63. for (i = 0; i < len; i++) {
  64. int x = read();
  65. if (x == -1 && i == 0) { // an immediate -1 returns -1
  66. return -1;
  67. }
  68. else if (x == -1) { // a later -1 returns the chars read so far
  69. break;
  70. }
  71. buf[off + i] = (byte) x;
  72. }
  73. return i;
  74. }

  75. public static String decode(String encoded) {
  76. return new String(decodeToBytes(encoded));
  77. }


  78. public static byte[] decodeToBytes(String encoded) {
  79. byte[] bytes = null;
  80. try {
  81. bytes = encoded.getBytes("8859_1");
  82. }
  83. catch (UnsupportedEncodingException ignored) { }

  84. BASE64Decoder in = new BASE64Decoder(
  85. new ByteArrayInputStream(bytes));

  86. ByteArrayOutputStream out =
  87. new ByteArrayOutputStream((int) (bytes.length * 0.67));

  88. try {
  89. byte[] buf = new byte[4 * 1024]; // 4K buffer
  90. int bytesRead;
  91. while ((bytesRead = in.read(buf)) != -1) {
  92. out.write(buf, 0, bytesRead);
  93. }
  94. out.close();

  95. return out.toByteArray();
  96. }
  97. catch (IOException ignored) { return null; }
  98. }

  99. public static void main(String[] args) throws Exception {
  100. if (args.length != 1) {
  101. System.err.println("Usage: java Base64Decoder fileToDecode");
  102. return;
  103. }

  104. BASE64Decoder decoder = null;
  105. try {
  106. decoder = new BASE64Decoder(
  107. new BufferedInputStream(
  108. new FileInputStream(args[0])));
  109. byte[] buf = new byte[4 * 1024]; // 4K buffer
  110. int bytesRead;
  111. while ((bytesRead = decoder.read(buf)) != -1) {
  112. System.out.write(buf, 0, bytesRead);
  113. }
  114. }
  115. finally {
  116. if (decoder != null) decoder.close();
  117. }
  118. }

  119. public static byte[] decodeBuffer(String key) {

  120. return decodeToBytes(key);
  121. }
  122. }

  123. class BASE64Encoder {
  124. private static final char last2byte = (char) Integer.parseInt("00000011", 2);
  125. private static final char last4byte = (char) Integer.parseInt("00001111", 2);
  126. private static final char last6byte = (char) Integer.parseInt("00111111", 2);
  127. private static final char lead6byte = (char) Integer.parseInt("11111100", 2);
  128. private static final char lead4byte = (char) Integer.parseInt("11110000", 2);
  129. private static final char lead2byte = (char) Integer.parseInt("11000000", 2);
  130. private static final char[] encodeTable = 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', '+', '/'};

  131. private BASE64Encoder() {
  132. }

  133. public static String encode(byte[] from) {
  134. StringBuffer to = new StringBuffer((int) (from.length * 1.34) + 3);
  135. int num = 0;
  136. char currentByte = 0;
  137. for (int i = 0; i < from.length; i++) {
  138. num = num % 8;
  139. while (num < 8) {
  140. switch (num) {
  141. case 0:
  142. currentByte = (char) (from[i] & lead6byte);
  143. currentByte = (char) (currentByte >>> 2);
  144. break;
  145. case 2:
  146. currentByte = (char) (from[i] & last6byte);
  147. break;
  148. case 4:
  149. currentByte = (char) (from[i] & last4byte);
  150. currentByte = (char) (currentByte << 2);
  151. if ((i + 1) < from.length) {
  152. currentByte |= (from[i + 1] & lead2byte) >>> 6;
  153. }
  154. break;
  155. case 6:
  156. currentByte = (char) (from[i] & last2byte);
  157. currentByte = (char) (currentByte << 4);
  158. if ((i + 1) < from.length) {
  159. currentByte |= (from[i + 1] & lead4byte) >>> 4;
  160. }
  161. break;
  162. }
  163. to.append(encodeTable[currentByte]);
  164. num += 6;
  165. }
  166. }
  167. if (to.length() % 4 != 0) {
  168. for (int i = 4 - to.length() % 4; i > 0; i--) {
  169. to.append("=");
  170. }
  171. }
  172. return to.toString();
  173. }

  174. public static String encodeBuffer(byte[] key) {
  175. return encode(key);
  176. }
  177. }
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

教学服务系统

GMT+8, 2025-4-30 12:37 , Processed in 0.017315 second(s), 19 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表