加密解密相关→EncryptUtils

 
   
  import android.util.Base64;
   
  import java.io.File;
  import java.io.FileInputStream;
  import java.io.IOException;
  import java.security.DigestInputStream;
  import java.security.InvalidKeyException;
  import java.security.MessageDigest;
  import java.security.NoSuchAlgorithmException;
  import java.security.SecureRandom;
   
  import javax.crypto.Cipher;
  import javax.crypto.Mac;
  import javax.crypto.spec.SecretKeySpec;
   
  /**
  * <pre>
  * author: Blankj
  * blog : http://blankj.com
  * time : 2016/8/2
  * desc : 加密解密相关的工具类
  * </pre>
  */
  public final class EncryptUtils {
   
  private EncryptUtils() {
  throw new UnsupportedOperationException("u can't instantiate me...");
  }
   
  /*********************** 哈希加密相关 ***********************/
  /**
  * MD2加密
  *
  * @param data 明文字符串
  * @return 16进制密文
  */
  public static String encryptMD2ToString(String data) {
  return encryptMD2ToString(data.getBytes());
  }
   
  /**
  * MD2加密
  *
  * @param data 明文字节数组
  * @return 16进制密文
  */
  public static String encryptMD2ToString(byte[] data) {
  return bytes2HexString(encryptMD2(data));
  }
   
  /**
  * MD2加密
  *
  * @param data 明文字节数组
  * @return 密文字节数组
  */
  public static byte[] encryptMD2(byte[] data) {
  return hashTemplate(data, "MD2");
  }
   
  /**
  * MD5加密
  *
  * @param data 明文字符串
  * @return 16进制密文
  */
  public static String encryptMD5ToString(String data) {
  return encryptMD5ToString(data.getBytes());
  }
   
  /**
  * MD5加密
  *
  * @param data 明文字符串
  * @param salt 盐
  * @return 16进制加盐密文
  */
  public static String encryptMD5ToString(String data, String salt) {
  return bytes2HexString(encryptMD5((data + salt).getBytes()));
  }
   
  /**
  * MD5加密
  *
  * @param data 明文字节数组
  * @return 16进制密文
  */
  public static String encryptMD5ToString(byte[] data) {
  return bytes2HexString(encryptMD5(data));
  }
   
  /**
  * MD5加密
  *
  * @param data 明文字节数组
  * @param salt 盐字节数组
  * @return 16进制加盐密文
  */
  public static String encryptMD5ToString(byte[] data, byte[] salt) {
  if (data == null || salt == null) return null;
  byte[] dataSalt = new byte[data.length + salt.length];
  System.arraycopy(data, 0, dataSalt, 0, data.length);
  System.arraycopy(salt, 0, dataSalt, data.length, salt.length);
  return bytes2HexString(encryptMD5(dataSalt));
  }
   
  /**
  * MD5加密
  *
  * @param data 明文字节数组
  * @return 密文字节数组
  */
  public static byte[] encryptMD5(byte[] data) {
  return hashTemplate(data, "MD5");
  }
   
  /**
  * MD5加密文件
  *
  * @param filePath 文件路径
  * @return 文件的16进制密文
  */
  public static String encryptMD5File2String(String filePath) {
  File file = isSpace(filePath) ? null : new File(filePath);
  return encryptMD5File2String(file);
  }
   
  /**
  * MD5加密文件
  *
  * @param filePath 文件路径
  * @return 文件的MD5校验码
  */
  public static byte[] encryptMD5File(String filePath) {
  File file = isSpace(filePath) ? null : new File(filePath);
  return encryptMD5File(file);
  }
   
  /**
  * MD5加密文件
  *
  * @param file 文件
  * @return 文件的16进制密文
  */
  public static String encryptMD5File2String(File file) {
  return bytes2HexString(encryptMD5File(file));
  }
   
  /**
  * MD5加密文件
  *
  * @param file 文件
  * @return 文件的MD5校验码
  */
  public static byte[] encryptMD5File(File file) {
  if (file == null) return null;
  FileInputStream fis = null;
  DigestInputStream digestInputStream;
  try {
  fis = new FileInputStream(file);
  MessageDigest md = MessageDigest.getInstance("MD5");
  digestInputStream = new DigestInputStream(fis, md);
  byte[] buffer = new byte[256 * 1024];
  while (digestInputStream.read(buffer) > 0) ;
  md = digestInputStream.getMessageDigest();
  return md.digest();
  } catch (NoSuchAlgorithmException | IOException e) {
  e.printStackTrace();
  return null;
  } finally {
  CloseUtils.closeIO(fis);
  }
  }
   
  /**
  * SHA1加密
  *
  * @param data 明文字符串
  * @return 16进制密文
  */
  public static String encryptSHA1ToString(String data) {
  return encryptSHA1ToString(data.getBytes());
  }
   
  /**
  * SHA1加密
  *
  * @param data 明文字节数组
  * @return 16进制密文
  */
  public static String encryptSHA1ToString(byte[] data) {
  return bytes2HexString(encryptSHA1(data));
  }
   
  /**
  * SHA1加密
  *
  * @param data 明文字节数组
  * @return 密文字节数组
  */
  public static byte[] encryptSHA1(byte[] data) {
  return hashTemplate(data, "SHA1");
  }
   
  /**
  * SHA224加密
  *
  * @param data 明文字符串
  * @return 16进制密文
  */
  public static String encryptSHA224ToString(String data) {
  return encryptSHA224ToString(data.getBytes());
  }
   
  /**
  * SHA224加密
  *
  * @param data 明文字节数组
  * @return 16进制密文
  */
  public static String encryptSHA224ToString(byte[] data) {
  return bytes2HexString(encryptSHA224(data));
  }
   
  /**
  * SHA224加密
  *
  * @param data 明文字节数组
  * @return 密文字节数组
  */
  public static byte[] encryptSHA224(byte[] data) {
  return hashTemplate(data, "SHA224");
  }
   
  /**
  * SHA256加密
  *
  * @param data 明文字符串
  * @return 16进制密文
  */
  public static String encryptSHA256ToString(String data) {
  return encryptSHA256ToString(data.getBytes());
  }
   
  /**
  * SHA256加密
  *
  * @param data 明文字节数组
  * @return 16进制密文
  */
  public static String encryptSHA256ToString(byte[] data) {
  return bytes2HexString(encryptSHA256(data));
  }
   
  /**
  * SHA256加密
  *
  * @param data 明文字节数组
  * @return 密文字节数组
  */
  public static byte[] encryptSHA256(byte[] data) {
  return hashTemplate(data, "SHA256");
  }
   
  /**
  * SHA384加密
  *
  * @param data 明文字符串
  * @return 16进制密文
  */
  public static String encryptSHA384ToString(String data) {
  return encryptSHA384ToString(data.getBytes());
  }
   
  /**
  * SHA384加密
  *
  * @param data 明文字节数组
  * @return 16进制密文
  */
  public static String encryptSHA384ToString(byte[] data) {
  return bytes2HexString(encryptSHA384(data));
  }
   
  /**
  * SHA384加密
  *
  * @param data 明文字节数组
  * @return 密文字节数组
  */
  public static byte[] encryptSHA384(byte[] data) {
  return hashTemplate(data, "SHA384");
  }
   
  /**
  * SHA512加密
  *
  * @param data 明文字符串
  * @return 16进制密文
  */
  public static String encryptSHA512ToString(String data) {
  return encryptSHA512ToString(data.getBytes());
  }
   
  /**
  * SHA512加密
  *
  * @param data 明文字节数组
  * @return 16进制密文
  */
  public static String encryptSHA512ToString(byte[] data) {
  return bytes2HexString(encryptSHA512(data));
  }
   
  /**
  * SHA512加密
  *
  * @param data 明文字节数组
  * @return 密文字节数组
  */
  public static byte[] encryptSHA512(byte[] data) {
  return hashTemplate(data, "SHA512");
  }
   
  /**
  * hash加密模板
  *
  * @param data 数据
  * @param algorithm 加密算法
  * @return 密文字节数组
  */
  private static byte[] hashTemplate(byte[] data, String algorithm) {
  if (data == null || data.length <= 0) return null;
  try {
  MessageDigest md = MessageDigest.getInstance(algorithm);
  md.update(data);
  return md.digest();
  } catch (NoSuchAlgorithmException e) {
  e.printStackTrace();
  return null;
  }
  }
   
  /**
  * HmacMD5加密
  *
  * @param data 明文字符串
  * @param key 秘钥
  * @return 16进制密文
  */
  public static String encryptHmacMD5ToString(String data, String key) {
  return encryptHmacMD5ToString(data.getBytes(), key.getBytes());
  }
   
  /**
  * HmacMD5加密
  *
  * @param data 明文字节数组
  * @param key 秘钥
  * @return 16进制密文
  */
  public static String encryptHmacMD5ToString(byte[] data, byte[] key) {
  return bytes2HexString(encryptHmacMD5(data, key));
  }
   
  /**
  * HmacMD5加密
  *
  * @param data 明文字节数组
  * @param key 秘钥
  * @return 密文字节数组
  */
  public static byte[] encryptHmacMD5(byte[] data, byte[] key) {
  return hmacTemplate(data, key, "HmacMD5");
  }
   
  /**
  * HmacSHA1加密
  *
  * @param data 明文字符串
  * @param key 秘钥
  * @return 16进制密文
  */
  public static String encryptHmacSHA1ToString(String data, String key) {
  return encryptHmacSHA1ToString(data.getBytes(), key.getBytes());
  }
   
  /**
  * HmacSHA1加密
  *
  * @param data 明文字节数组
  * @param key 秘钥
  * @return 16进制密文
  */
  public static String encryptHmacSHA1ToString(byte[] data, byte[] key) {
  return bytes2HexString(encryptHmacSHA1(data, key));
  }
   
  /**
  * HmacSHA1加密
  *
  * @param data 明文字节数组
  * @param key 秘钥
  * @return 密文字节数组
  */
  public static byte[] encryptHmacSHA1(byte[] data, byte[] key) {
  return hmacTemplate(data, key, "HmacSHA1");
  }
   
  /**
  * HmacSHA224加密
  *
  * @param data 明文字符串
  * @param key 秘钥
  * @return 16进制密文
  */
  public static String encryptHmacSHA224ToString(String data, String key) {
  return encryptHmacSHA224ToString(data.getBytes(), key.getBytes());
  }
   
  /**
  * HmacSHA224加密
  *
  * @param data 明文字节数组
  * @param key 秘钥
  * @return 16进制密文
  */
  public static String encryptHmacSHA224ToString(byte[] data, byte[] key) {
  return bytes2HexString(encryptHmacSHA224(data, key));
  }
   
  /**
  * HmacSHA224加密
  *
  * @param data 明文字节数组
  * @param key 秘钥
  * @return 密文字节数组
  */
  public static byte[] encryptHmacSHA224(byte[] data, byte[] key) {
  return hmacTemplate(data, key, "HmacSHA224");
  }
   
  /**
  * HmacSHA256加密
  *
  * @param data 明文字符串
  * @param key 秘钥
  * @return 16进制密文
  */
  public static String encryptHmacSHA256ToString(String data, String key) {
  return encryptHmacSHA256ToString(data.getBytes(), key.getBytes());
  }
   
  /**
  * HmacSHA256加密
  *
  * @param data 明文字节数组
  * @param key 秘钥
  * @return 16进制密文
  */
  public static String encryptHmacSHA256ToString(byte[] data, byte[] key) {
  return bytes2HexString(encryptHmacSHA256(data, key));
  }
   
  /**
  * HmacSHA256加密
  *
  * @param data 明文字节数组
  * @param key 秘钥
  * @return 密文字节数组
  */
  public static byte[] encryptHmacSHA256(byte[] data, byte[] key) {
  return hmacTemplate(data, key, "HmacSHA256");
  }
   
  /**
  * HmacSHA384加密
  *
  * @param data 明文字符串
  * @param key 秘钥
  * @return 16进制密文
  */
  public static String encryptHmacSHA384ToString(String data, String key) {
  return encryptHmacSHA384ToString(data.getBytes(), key.getBytes());
  }
   
  /**
  * HmacSHA384加密
  *
  * @param data 明文字节数组
  * @param key 秘钥
  * @return 16进制密文
  */
  public static String encryptHmacSHA384ToString(byte[] data, byte[] key) {
  return bytes2HexString(encryptHmacSHA384(data, key));
  }
   
  /**
  * HmacSHA384加密
  *
  * @param data 明文字节数组
  * @param key 秘钥
  * @return 密文字节数组
  */
  public static byte[] encryptHmacSHA384(byte[] data, byte[] key) {
  return hmacTemplate(data, key, "HmacSHA384");
  }
   
  /**
  * HmacSHA512加密
  *
  * @param data 明文字符串
  * @param key 秘钥
  * @return 16进制密文
  */
  public static String encryptHmacSHA512ToString(String data, String key) {
  return encryptHmacSHA512ToString(data.getBytes(), key.getBytes());
  }
   
  /**
  * HmacSHA512加密
  *
  * @param data 明文字节数组
  * @param key 秘钥
  * @return 16进制密文
  */
  public static String encryptHmacSHA512ToString(byte[] data, byte[] key) {
  return bytes2HexString(encryptHmacSHA512(data, key));
  }
   
  /**
  * HmacSHA512加密
  *
  * @param data 明文字节数组
  * @param key 秘钥
  * @return 密文字节数组
  */
  public static byte[] encryptHmacSHA512(byte[] data, byte[] key) {
  return hmacTemplate(data, key, "HmacSHA512");
  }
   
  /**
  * Hmac加密模板
  *
  * @param data 数据
  * @param key 秘钥
  * @param algorithm 加密算法
  * @return 密文字节数组
  */
  private static byte[] hmacTemplate(byte[] data, byte[] key, String algorithm) {
  if (data == null || data.length == 0 || key == null || key.length == 0) return null;
  try {
  SecretKeySpec secretKey = new SecretKeySpec(key, algorithm);
  Mac mac = Mac.getInstance(algorithm);
  mac.init(secretKey);
  return mac.doFinal(data);
  } catch (InvalidKeyException | NoSuchAlgorithmException e) {
  e.printStackTrace();
  return null;
  }
  }
   
  /************************ DES加密相关 ***********************/
  /**
  * DES转变
  * <p>法算法名称/加密模式/填充方式</p>
  * <p>加密模式有:电子密码本模式ECB、加密块链模式CBC、加密反馈模式CFB、输出反馈模式OFB</p>
  * <p>填充方式有:NoPadding、ZerosPadding、PKCS5Padding</p>
  */
  public static String DES_Transformation = "DES/ECB/NoPadding";
  private static final String DES_Algorithm = "DES";
   
  /**
  * DES加密后转为Base64编码
  *
  * @param data 明文
  * @param key 8字节秘钥
  * @return Base64密文
  */
  public static byte[] encryptDES2Base64(byte[] data, byte[] key) {
  return base64Encode(encryptDES(data, key));
  }
   
  /**
  * DES加密后转为16进制
  *
  * @param data 明文
  * @param key 8字节秘钥
  * @return 16进制密文
  */
  public static String encryptDES2HexString(byte[] data, byte[] key) {
  return bytes2HexString(encryptDES(data, key));
  }
   
  /**
  * DES加密
  *
  * @param data 明文
  * @param key 8字节秘钥
  * @return 密文
  */
  public static byte[] encryptDES(byte[] data, byte[] key) {
  return desTemplate(data, key, DES_Algorithm, DES_Transformation, true);
  }
   
  /**
  * DES解密Base64编码密文
  *
  * @param data Base64编码密文
  * @param key 8字节秘钥
  * @return 明文
  */
  public static byte[] decryptBase64DES(byte[] data, byte[] key) {
  return decryptDES(base64Decode(data), key);
  }
   
  /**
  * DES解密16进制密文
  *
  * @param data 16进制密文
  * @param key 8字节秘钥
  * @return 明文
  */
  public static byte[] decryptHexStringDES(String data, byte[] key) {
  return decryptDES(hexString2Bytes(data), key);
  }
   
  /**
  * DES解密
  *
  * @param data 密文
  * @param key 8字节秘钥
  * @return 明文
  */
  public static byte[] decryptDES(byte[] data, byte[] key) {
  return desTemplate(data, key, DES_Algorithm, DES_Transformation, false);
  }
   
  /************************ 3DES加密相关 ***********************/
  /**
  * 3DES转变
  * <p>法算法名称/加密模式/填充方式</p>
  * <p>加密模式有:电子密码本模式ECB、加密块链模式CBC、加密反馈模式CFB、输出反馈模式OFB</p>
  * <p>填充方式有:NoPadding、ZerosPadding、PKCS5Padding</p>
  */
  public static String TripleDES_Transformation = "DESede/ECB/NoPadding";
  private static final String TripleDES_Algorithm = "DESede";
   
   
  /**
  * 3DES加密后转为Base64编码
  *
  * @param data 明文
  * @param key 24字节秘钥
  * @return Base64密文
  */
  public static byte[] encrypt3DES2Base64(byte[] data, byte[] key) {
  return base64Encode(encrypt3DES(data, key));
  }
   
  /**
  * 3DES加密后转为16进制
  *
  * @param data 明文
  * @param key 24字节秘钥
  * @return 16进制密文
  */
  public static String encrypt3DES2HexString(byte[] data, byte[] key) {
  return bytes2HexString(encrypt3DES(data, key));
  }
   
  /**
  * 3DES加密
  *
  * @param data 明文
  * @param key 24字节密钥
  * @return 密文
  */
  public static byte[] encrypt3DES(byte[] data, byte[] key) {
  return desTemplate(data, key, TripleDES_Algorithm, TripleDES_Transformation, true);
  }
   
  /**
  * 3DES解密Base64编码密文
  *
  * @param data Base64编码密文
  * @param key 24字节秘钥
  * @return 明文
  */
  public static byte[] decryptBase64_3DES(byte[] data, byte[] key) {
  return decrypt3DES(base64Decode(data), key);
  }
   
  /**
  * 3DES解密16进制密文
  *
  * @param data 16进制密文
  * @param key 24字节秘钥
  * @return 明文
  */
  public static byte[] decryptHexString3DES(String data, byte[] key) {
  return decrypt3DES(hexString2Bytes(data), key);
  }
   
  /**
  * 3DES解密
  *
  * @param data 密文
  * @param key 24字节密钥
  * @return 明文
  */
  public static byte[] decrypt3DES(byte[] data, byte[] key) {
  return desTemplate(data, key, TripleDES_Algorithm, TripleDES_Transformation, false);
  }
   
  /************************ AES加密相关 ***********************/
  /**
  * AES转变
  * <p>法算法名称/加密模式/填充方式</p>
  * <p>加密模式有:电子密码本模式ECB、加密块链模式CBC、加密反馈模式CFB、输出反馈模式OFB</p>
  * <p>填充方式有:NoPadding、ZerosPadding、PKCS5Padding</p>
  */
  public static String AES_Transformation = "AES/ECB/NoPadding";
  private static final String AES_Algorithm = "AES";
   
   
  /**
  * AES加密后转为Base64编码
  *
  * @param data 明文
  * @param key 16、24、32字节秘钥
  * @return Base64密文
  */
  public static byte[] encryptAES2Base64(byte[] data, byte[] key) {
  return base64Encode(encryptAES(data, key));
  }
   
  /**
  * AES加密后转为16进制
  *
  * @param data 明文
  * @param key 16、24、32字节秘钥
  * @return 16进制密文
  */
  public static String encryptAES2HexString(byte[] data, byte[] key) {
  return bytes2HexString(encryptAES(data, key));
  }
   
  /**
  * AES加密
  *
  * @param data 明文
  * @param key 16、24、32字节秘钥
  * @return 密文
  */
  public static byte[] encryptAES(byte[] data, byte[] key) {
  return desTemplate(data, key, AES_Algorithm, AES_Transformation, true);
  }
   
  /**
  * AES解密Base64编码密文
  *
  * @param data Base64编码密文
  * @param key 16、24、32字节秘钥
  * @return 明文
  */
  public static byte[] decryptBase64AES(byte[] data, byte[] key) {
  return decryptAES(base64Decode(data), key);
  }
   
  /**
  * AES解密16进制密文
  *
  * @param data 16进制密文
  * @param key 16、24、32字节秘钥
  * @return 明文
  */
  public static byte[] decryptHexStringAES(String data, byte[] key) {
  return decryptAES(hexString2Bytes(data), key);
  }
   
  /**
  * AES解密
  *
  * @param data 密文
  * @param key 16、24、32字节秘钥
  * @return 明文
  */
  public static byte[] decryptAES(byte[] data, byte[] key) {
  return desTemplate(data, key, AES_Algorithm, AES_Transformation, false);
  }
   
  /**
  * DES加密模板
  *
  * @param data 数据
  * @param key 秘钥
  * @param algorithm 加密算法
  * @param transformation 转变
  * @param isEncrypt {@code true}: 加密 {@code false}: 解密
  * @return 密文或者明文,适用于DES,3DES,AES
  */
  public static byte[] desTemplate(byte[] data, byte[] key, String algorithm, String transformation, boolean isEncrypt) {
  if (data == null || data.length == 0 || key == null || key.length == 0) return null;
  try {
  SecretKeySpec keySpec = new SecretKeySpec(key, algorithm);
  Cipher cipher = Cipher.getInstance(transformation);
  SecureRandom random = new SecureRandom();
  cipher.init(isEncrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE, keySpec, random);
  return cipher.doFinal(data);
  } catch (Throwable e) {
  e.printStackTrace();
  return null;
  }
  }
   
  private static final char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
   
  /**
  * byteArr转hexString
  * <p>例如:</p>
  * bytes2HexString(new byte[] { 0, (byte) 0xa8 }) returns 00A8
  *
  * @param bytes 字节数组
  * @return 16进制大写字符串
  */
  private static String bytes2HexString(byte[] bytes) {
  if (bytes == null) return null;
  int len = bytes.length;
  if (len <= 0) return null;
  char[] ret = new char[len << 1];
  for (int i = 0, j = 0; i < len; i++) {
  ret[j++] = hexDigits[bytes[i] >>> 4 & 0x0f];
  ret[j++] = hexDigits[bytes[i] & 0x0f];
  }
  return new String(ret);
  }
   
   
  /**
  * hexString转byteArr
  * <p>例如:</p>
  * hexString2Bytes("00A8") returns { 0, (byte) 0xA8 }
  *
  * @param hexString 十六进制字符串
  * @return 字节数组
  */
  private static byte[] hexString2Bytes(String hexString) {
  if (isSpace(hexString)) return null;
  int len = hexString.length();
  if (len % 2 != 0) {
  hexString = "0" + hexString;
  len = len + 1;
  }
  char[] hexBytes = hexString.toUpperCase().toCharArray();
  byte[] ret = new byte[len >> 1];
  for (int i = 0; i < len; i += 2) {
  ret[i >> 1] = (byte) (hex2Dec(hexBytes[i]) << 4 | hex2Dec(hexBytes[i + 1]));
  }
  return ret;
  }
   
  /**
  * hexChar转int
  *
  * @param hexChar hex单个字节
  * @return 0..15
  */
  private static int hex2Dec(char hexChar) {
  if (hexChar >= '0' && hexChar <= '9') {
  return hexChar - '0';
  } else if (hexChar >= 'A' && hexChar <= 'F') {
  return hexChar - 'A' + 10;
  } else {
  throw new IllegalArgumentException();
  }
  }
   
  /**
  * Base64编码
  *
  * @param input 要编码的字节数组
  * @return Base64编码后的字符串
  */
  private static byte[] base64Encode(byte[] input) {
  return Base64.encode(input, Base64.NO_WRAP);
  }
   
  /**
  * Base64解码
  *
  * @param input 要解码的字符串
  * @return Base64解码后的字符串
  */
  private static byte[] base64Decode(byte[] input) {
  return Base64.decode(input, Base64.NO_WRAP);
  }
   
  private static boolean isSpace(String s) {
  if (s == null) return true;
  for (int i = 0, len = s.length(); i < len; ++i) {
  if (!Character.isWhitespace(s.charAt(i))) {
  return false;
  }
  }
  return true;
  }
  }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值