java 版DES和MAC算法

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: java 版DES和MAC算法
import java.io.UnsupportedEncodingException;
import util.Util;
/**
 * PBOC3DES 加密算法
 * @author Administrator
 *
 */
public class PBOC3DES {
  private static int HEX = 0;
  private static int ASC = 1;
  private static int[][] subKey = new int[16][48];
  /** ***************************压缩替换S-Box************************************************* */
  private static final int[][] s1 = {
      { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7 },
      { 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8 },
      { 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0 },
      { 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 } };
  private static final int[][] s2 = {
      { 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10 },
      { 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5 },
      { 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15 },
      { 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 } };
  private static final int[][] s3 = {
      { 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8 },
      { 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1 },
      { 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7 },
      { 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 } };
  private static final int[][] s4 = {
      { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15 },
      { 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9 },// erorr
      { 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4 },
      { 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 } };
  private static final int[][] s5 = {
      { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9 },
      { 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6 },
      { 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14 },
      { 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 } };
  private static final int[][] s6 = {
      { 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11 },
      { 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8 },
      { 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6 },
      { 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 } };
  private static final int[][] s7 = {
      { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1 },
      { 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6 },
      { 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2 },
      { 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 } };
  private static final int[][] s8 = {
      { 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7 },
      { 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2 },
      { 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8 },
      { 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 } };
  private static final int[] ip = { 58, 50, 42, 34, 26, 18, 10, 2, 60, 52,
    44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48,
    40, 32, 24, 16, 8, 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35,
    27, 19, 11, 3, 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31,
    23, 15, 7 };
  private static final int[] _ip = { 40, 8, 48, 16, 56, 24, 64, 32, 39, 7,
    47, 15, 55, 23, 63, 31, 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45,
    13, 53, 21, 61, 29, 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11,
    51, 19, 59, 27, 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49,
    17, 57, 25 };
  // 每次密钥循环左移位数
    private static final int[] LS = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2,
        2, 1 };
  /**
   * 计算MAC(hex)
   * PBOC_3DES_MAC(16的整数补8000000000000000)
   * 前n-1组使用单长密钥DES 使用密钥是密钥的左8字节)
   * 最后1组使用双长密钥3DES (使用全部16字节密钥)
   * @param key 密钥(32byte)
   * @param 初始向量0000000000000000
   * @param data 数据
   * @param type  HEX:16进制的数据    ASC:字符串
   * @return mac
   */
  public static String PBOC_3DES_MAC(String data, String key,int type){
    String vector = "0000000000000000";
    if (key.length()!=32){
      return null;
    }
    if (type == ASC) {
      data = ASC_2_HEX(data);
    }
    int len = data.length();
    int arrLen = len / 16 + 1;
    String[] D = new String[arrLen];
    if (len % 16 == 0) {
      data += "8000000000000000";
    } else {
      data += "80";
      for (int i = 0; i < 15 - len % 16; i++) {
        data += "00";
      }
    }
    for (int i = 0; i < arrLen; i++) {
      D[i] = data.substring(i * 16, i * 16 + 16);
    }
    // D0 Xor Vector
    String I = xOr(D[0], vector);
    String O = null;
    String kl = key.substring(0, 16);
    for (int i = 1; i < arrLen; i++) {
      O = DES_1(I, kl, 0);
      I = xOr(D[i], O);
    }
    I = DES_3(I, key, 0);
    return I;
  }
  /**
   * 
   * 三重DES算法(双长密32byte))
   * 密钥K1和K2
   * 1、先用K1加密明文
   * 2、接K2对上的结果进行解
   * 3、然后用K1对上的结果进行加
   * @param source
   * @param key
   * @param type
   *            0:encrypt 1:discrypt
   * @return
   */
  public static String DES_3(String source, String key, int type) {
    if (key.length() != 32 || source.length() != 16)
      return null;
    String temp = null;
    String K1 = key.substring(0, key.length() / 2);
    String K2 = key.substring(key.length() / 2);
//    System.out.println("K1--->" + K1);
//    System.out.println("K2--->" + K2);
    if (type == 0) {
      temp = encryption(source, K1);
//      System.out.println("step1--->" + temp);
      temp = discryption(temp, K2);
//      System.out.println("step2--->" + temp);
      return encryption(temp, K1);
    }
    if (type == 1) {
      temp = discryption(source, K1);
      temp = encryption(temp, K2);
      return discryption(temp, K1);
    }
    return null;
  }
  /**
   * DES解密--->对称密钥
   * 解密算法与加密算法基本相同,不同之处仅在于轮子密钥的使用顺序逆序,即解密的第1
   * 轮子密钥为加密的6 轮子密钥,解密的 轮子密钥为加密的5 轮子密钥,…,
   * 解密的第16 轮子密钥为加密的 轮子密钥
   * @param source密文
   * @param key密钥
   * @return
   * 
   */
  public static String discryption(String source, String key) {
    String str = "";
    int[] data = string2Binary(source);// 64bit
    // 第一步初始置
    data = changeIP(data);
    int[] left = new int[32];
    int[] right = new int[32];
    int[] tmp = new int[32];
    for (int j = 0; j < 32; j++) {
      left[j] = data[j];
      right[j] = data[j + 32];
    }
    setKey(key);// sub key ok
    for (int i = 16; i > 0; i--) {
      // 获取(48bit)的轮子密
      /** *******不同之处********* */
      int[] sKey = subKey[i - 1];
      tmp = left;
      // R1 = L0
      left = right;
      // L1 = R0 ^ f(L0,K1)
      int[] fTemp = f(right, sKey);// 32bit
      right = diffOr(tmp, fTemp);
    }
    // 组合的时候,左右调换**************************************************
    for (int i = 0; i < 32; i++) {
      data[i] = right[i];
      data[32 + i] = left[i];
    }
    data = changeInverseIP(data);
    for (int i = 0; i < data.length; i++) {
      str += data[i];
    }
    str = binary2ASC(str);
    return str;
  }
  /**
   * @param R(2bit)
   * @param K(48bit的轮子密
   * @return 32bit
   */
  public static int[] f(int[] R, int[] K) {
    int[] dest = new int[32];
    int[] temp = new int[48];
    // 先将输入32bit扩展8bit
    int[] expendR = expend(R);// 48bit
    // 与轮子密钥进行异或运
    temp = diffOr(expendR, K);
    // 压缩2bit
    dest = press(temp);
    return dest;
  }
  /**
   * 8bit压缩2bit
   * @param source(48bit)
   * @return R(32bit) B=E(R)⊕K,将48 位的B 分成8 个分组,B=B1B2B3B4B5B6B7B8
   */
  public static int[] press(int[] source) {
    int[] ret = new int[32];
    int[][] temp = new int[8][6];
    int[][][] s = { s1, s2, s3, s4, s5, s6, s7, s8 };
    StringBuffer str = new StringBuffer();
    for (int i = 0; i < 8; i++) {
      for (int j = 0; j < 6; j++) {
        temp[i][j] = source[i * 6 + j];
      }
    }
    for (int i = 0; i < 8; i++) {
      // (16)
      int x = temp[i][0] * 2 + temp[i][5];
      // (2345)
      int y = temp[i][1] * 8 + temp[i][2] * 4 + temp[i][3] * 2
          + temp[i][4];
      int val = s[i][x][y];
      String ch = int2Hex(val);
      // System.out.println("x=" + x + ",y=" + y + "-->" + ch);
      // String ch = Integer.toBinaryString(val);
      str.append(ch);
    }
    // System.out.println(str.toString());
    ret = string2Binary(str.toString());
    // printArr(ret);
    // 置换P
    ret = dataP(ret);
    return ret;
  }
  /**
   * 置换P(32bit)
   * @param source
   * @return
   */
  public static int[] dataP(int[] source) {
    int[] dest = new int[32];
    int[] temp = { 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31,
        10, 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25 };
    int len = source.length;
    for (int i = 0; i < len; i++) {
      dest[i] = source[temp[i] - 1];
    }
    return dest;
  }
  /**
   * 将int转换成Hex
   * @param i
   * @return
   * @throws Exception
   */
  public static String int2Hex(int i) {
    switch (i) {
    case 0:
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
    case 6:
    case 7:
    case 8:
    case 9:
      return "" + i;
    case 10:
      return "A";
    case 11:
      return "B";
    case 12:
      return "C";
    case 13:
      return "D";
    case 14:
      return "E";
    case 15:
      return "F";
    default:
      return null;
    }
  }
  /**
   * 2bit扩展8bit
   * @param source
   * @return
   */
  public static int[] expend(int[] source) {
    int[] ret = new int[48];
    int[] temp = { 32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12,
        13, 12, 13, 14, 15, 16, 17, 16, 17, 18, 19, 20, 21, 20, 21, 22,
        23, 24, 25, 24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1 };
    for (int i = 0; i < 48; i++) {
      ret[i] = source[temp[i] - 1];
    }
    return ret;
  }
  /**
   * IP-1逆置
   * @param source
   * @return
   */
  public static int[] changeInverseIP(int[] source) {
    int[] dest = new int[64];
    for (int i = 0; i < 64; i++) {
      dest[i] = source[_ip[i] - 1];
    }
    return dest;
  }
  /**
   * 
   * 获取轮子密钥(48bit)
   * 
   * @param source
   * 
   * @return
   * 
   */
  public static void setKey(String source) {
    if (subKey.length > 0)
      subKey = new int[16][48];
    // 装换4bit
    int[] temp = string2Binary(source);
    // 6bit均分成两部分
    int[] left = new int[28];
    int[] right = new int[28];
    // 经过PC-14bit转换6bit
    int[] temp1 = new int[56];
    temp1 = keyPC_1(temp);
    // printArr(temp1);
    // 将经过转换的temp1均分成两部分
    for (int i = 0; i < 28; i++) {
      left[i] = temp1[i];
      right[i] = temp1[i + 28];
    }
    // 经过16次循环左移,然后PC-2置换
    for (int i = 0; i < 16; i++) {
      left = keyLeftMove(left, LS[i]);
      right = keyLeftMove(right, LS[i]);
      for (int j = 0; j < 28; j++) {
        temp1[j] = left[j];
        temp1[j + 28] = right[j];
      }
      // printArr(temp1);
      subKey[i] = keyPC_2(temp1);
    }
  }
  /**
   * 
   * 6bit的密钥转换成48bit
   * @param source
   * @return
   * 
   */
  public static int[] keyPC_2(int[] source) {
    int[] dest = new int[48];
    int[] temp = { 14, 17, 11, 24, 1, 5,
    3, 28, 15, 6, 21, 10,
    23, 19, 12, 4, 26, 8,
    16, 7, 27, 20, 13, 2,
    41, 52, 31, 37, 47, 55,
    30, 40, 51, 45, 33, 48,
    44, 49, 39, 56, 34, 53,
    46, 42, 50, 36, 29, 32 };
    for (int i = 0; i < 48; i++) {
      dest[i] = source[temp[i] - 1];
    }
    return dest;
  }
  /**
   * 
   * 将密钥循环左移i
   * @param source 二进制密钥数
   * @param i 循环左移位数
   * @return
   * 
   */
  public static int[] keyLeftMove(int[] source, int i) {
    int temp = 0;
    int len = source.length;
    int ls = LS[i];
    // System.out.println("len" + len + ",LS[" + i + "]=" + ls);
    for (int k = 0; k < ls; k++) {
      temp = source[0];
      for (int j = 0; j < len - 1; j++) {
        source[j] = source[j + 1];
      }
      source[len - 1] = temp;
    }
    return source;
  }
  /**
   * 
   * 4bit的密钥转换成56bit
   * @param source
   * @return
   * 
   */
  public static int[] keyPC_1(int[] source) {
    int[] dest = new int[56];
    int[] temp = { 57, 49, 41, 33, 25, 17, 9,
    1, 58, 50, 42, 34, 26, 18,
    10, 2, 59, 51, 43, 35, 27,
    19, 11, 3, 60, 52, 44, 36,
    63, 55, 47, 39, 31, 23, 15,
    7, 62, 54, 46, 38, 30, 22,
    14, 6, 61, 53, 45, 37, 29,
    21, 13, 5, 28, 20, 12, 4 };
    for (int i = 0; i < 56; i++) {
      dest[i] = source[temp[i] - 1];
    }
    return dest;
  }
  /**
   * 
   * 单长密钥DES(16byte)
   * @param source
   * @param key
   * @param type 0:encrypt 1:discrypt
   * @return
   * 
   */
  public static String DES_1(String source, String key, int type) {
    if (source.length() != 16 || key.length() != 16)
      return null;
    if (type == 0) {
      return encryption(source, key);
    }
    if (type == 1) {
      return discryption(source, key);
    }
    return null;
  }
  /**
   * IP初始置换
   * @param source
   * @return
   */
  public static int[] changeIP(int[] source) {
    int[] dest = new int[64];
    for (int i = 0; i < 64; i++) {
      dest[i] = source[ip[i] - 1];
    }
    return dest;
  }
  /**
   * 
   * DES加密--->对称密钥
   * D = Ln(32bit)+Rn(32bit)
   * 经过16轮置
   * @param D(16byte)明文
   * @param K(16byte)轮子密钥
   * @return (16byte)密文
   */
  public static String encryption(String D, String K) {
    String str = "";
    int[] temp = new int[64];
    int[] data = string2Binary(D);
    // 第一步初始置
    data = changeIP(data);
    int[][] left = new int[17][32];
    int[][] right = new int[17][32];
    for (int j = 0; j < 32; j++) {
      left[0][j] = data[j];
      right[0][j] = data[j + 32];
    }
    setKey(K);// sub key ok
    for (int i = 1; i < 17; i++) {
      // 获取(48bit)的轮子密
      int[] key = subKey[i - 1];
      // L1 = R0
      left[i] = right[i - 1];
      // R1 = L0 ^ f(R0,K1)
      int[] fTemp = f(right[i - 1], key);// 32bit
      right[i] = diffOr(left[i - 1], fTemp);
    }
    // 组合的时候,左右调换**************************************************
    for (int i = 0; i < 32; i++) {
      temp[i] = right[16][i];
      temp[32 + i] = left[16][i];
    }
    temp = changeInverseIP(temp);
    str = binary2ASC(intArr2Str(temp));
    return str;
  }
  /**
   * 将ASC字符串转16进制字符
   * @param asc
   * @return
   */
  public static String ASC_2_HEX(String asc) {
    StringBuffer hex = new StringBuffer();
    try {
      byte[] bs = asc.toUpperCase().getBytes("UTF-8");
      for (byte b : bs) {
        hex.append(Integer.toHexString(new Byte(b).intValue()));
      }
    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
    }
    return hex.toString();
  }
  /**
   * 
   * 将s1和s2做异或,然后返回
   * @param s1
   * @param s2
   * @return
   * 
   */
  public static String xOr(String s1, String s2) {
    int[] iArr = diffOr(string2Binary(s1), string2Binary(s2));
    return binary2ASC(intArr2Str(iArr));
  }
  /**
   * 将二进制字符串转换成十六进制字符
   * @param s
   * @return
   */
  public static String binary2ASC(String s) {
    String str = "";
    int ii = 0;
    int len = s.length();
    // 不够4bit左补0
    if (len % 4 != 0) {
      while (ii < 4 - len % 4) {
        s = "0" + s;
      }
    }
    for (int i = 0; i < len / 4; i++) {
      str += binary2Hex(s.substring(i * 4, i * 4 + 4));
    }
    return str;
  }
  /**
   * s位长度的二进制字符串
   * @param s
   * @return
   */
  public static String binary2Hex(String s) {
    int len = s.length();
    int result = 0;
    int k = 0;
    if (len > 4)
      return null;
    for (int i = len; i > 0; i--) {
      result += Integer.parseInt(s.substring(i - 1, i)) * getXY(2, k);
      k++;
    }
    switch (result) {
    case 0:
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
    case 6:
    case 7:
    case 8:
    case 9:
      return "" + result;
    case 10:
      return "A";
    case 11:
      return "B";
    case 12:
      return "C";
    case 13:
      return "D";
    case 14:
      return "E";
    case 15:
      return "F";
    default:
      return null;
    }
  }
  /**
   * 返回x的y次方
   * @param x
   * @param y
   * @return
   */
  public static int getXY(int x, int y) {
    int temp = x;
    if (y == 0)
      x = 1;
    for (int i = 2; i <= y; i++) {
      x *= temp;
    }
    return x;
  }
  /**
   * 将字符串转换成二进制数组
   * @param source :16字节
   * @return
   */
  public static int[] string2Binary(String source) {
    int len = source.length();
    int[] dest = new int[len * 4];
    char[] arr = source.toCharArray();
    for (int i = 0; i < len; i++) {
      int t = 0;
      try {
        t = getIntByChar(arr[i]);
        // System.out.println(arr[i]);
      } catch (Exception e) {
        e.printStackTrace();
      }
      String[] str = Integer.toBinaryString(t).split("");
      int k = i * 4 + 3;
      for (int j = str.length - 1; j > 0; j--) {
        dest[k] = Integer.parseInt(str[j]);
        k--;
      }
    }
    return dest;
  }
  /**
   * 将十六进制A--F转换成对应数
   * @param ch
   * @return
   * @throws Exception
   */
  public static int getIntByChar(char ch) throws Exception {
    char t = Character.toUpperCase(ch);
    int i = 0;
    switch (t) {
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
      i = Integer.parseInt(Character.toString(t));
      break;
    case 'A':
      i = 10;
      break;
    case 'B':
      i = 11;
      break;
    case 'C':
      i = 12;
      break;
    case 'D':
      i = 13;
      break;
    case 'E':
      i = 14;
      break;
    case 'F':
      i = 15;
      break;
    default:
      throw new Exception("getIntByChar was wrong");
    }
    return i;
  }
  /**
   * 两个等长的数组做异或
   * @param source1
   * @param source2
   * @return
   */
  public static int[] diffOr(int[] source1, int[] source2) {
    int len = source1.length;
    int[] dest = new int[len];
    for (int i = 0; i < len; i++) {
      dest[i] = source1[i] ^ source2[i];
    }
    return dest;
  }
  /**
   * 将int类型数组拼接成字符串
   * @param arr
   * @return
   */
  public static String intArr2Str(int[] arr) {
    StringBuffer sb = new StringBuffer();
    for (int i = 0; i < arr.length; i++) {
      sb.append(arr[i]);
    }
    return sb.toString();
  }
  public static void main(String[] args) {
    byte[] data = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,0x08};
    byte[] key = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
        0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
    String result = PBOC_3DES_MAC(Util.bytesToHexString(data),Util.bytesToHexString(key),HEX);
    System.out.println("PBOC3DES加密结果为:"+result);
  }
}
相关文章
|
19天前
|
存储 人工智能 算法
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
这篇文章详细介绍了Dijkstra和Floyd算法,这两种算法分别用于解决单源和多源最短路径问题,并且提供了Java语言的实现代码。
54 3
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
|
3月前
|
负载均衡 NoSQL 算法
一天五道Java面试题----第十天(简述Redis事务实现--------->负载均衡算法、类型)
这篇文章是关于Java面试中Redis相关问题的笔记,包括Redis事务实现、集群方案、主从复制原理、CAP和BASE理论以及负载均衡算法和类型。
一天五道Java面试题----第十天(简述Redis事务实现--------->负载均衡算法、类型)
|
3月前
|
搜索推荐 算法 Java
手写快排:教你用Java写出高效排序算法!
快速排序(QuickSort)是经典的排序算法之一,基于分治思想,平均时间复杂度为O(n log n),广泛应用于各种场合。在这篇文章中,我们将手写一个Java版本的快速排序,从基础实现到优化策略,并逐步解析代码背后的逻辑。
119 1
|
21天前
|
算法 搜索推荐 Java
java 后端 使用 Graphics2D 制作海报,画echarts图,带工具类,各种细节:如头像切割成圆形,文字换行算法(完美实验success),解决画上文字、图片后不清晰问题
这篇文章介绍了如何使用Java后端技术,结合Graphics2D和Echarts等工具,生成包含个性化信息和图表的海报,并提供了详细的代码实现和GitHub项目链接。
74 0
java 后端 使用 Graphics2D 制作海报,画echarts图,带工具类,各种细节:如头像切割成圆形,文字换行算法(完美实验success),解决画上文字、图片后不清晰问题
|
25天前
|
算法 Java 数据中心
探讨面试常见问题雪花算法、时钟回拨问题,java中优雅的实现方式
【10月更文挑战第2天】在大数据量系统中,分布式ID生成是一个关键问题。为了保证在分布式环境下生成的ID唯一、有序且高效,业界提出了多种解决方案,其中雪花算法(Snowflake Algorithm)是一种广泛应用的分布式ID生成算法。本文将详细介绍雪花算法的原理、实现及其处理时钟回拨问题的方法,并提供Java代码示例。
55 2
|
21天前
|
算法 Java Linux
java制作海报一:java使用Graphics2D 在图片上写字,文字换行算法详解
这篇文章介绍了如何在Java中使用Graphics2D在图片上绘制文字,并实现自动换行的功能。
56 0
|
29天前
|
算法 Java 测试技术
数据结构 —— Java自定义代码实现顺序表,包含测试用例以及ArrayList的使用以及相关算法题
文章详细介绍了如何用Java自定义实现一个顺序表类,包括插入、删除、获取数据元素、求数据个数等功能,并对顺序表进行了测试,最后还提及了Java中自带的顺序表实现类ArrayList。
17 0
|
3月前
|
设计模式 缓存 算法
揭秘策略模式:如何用Java设计模式轻松切换算法?
【8月更文挑战第30天】设计模式是解决软件开发中特定问题的可重用方案。其中,策略模式是一种常用的行为型模式,允许在运行时选择算法行为。它通过定义一系列可互换的算法来封装具体的实现,使算法的变化与客户端分离。例如,在电商系统中,可以通过定义 `DiscountStrategy` 接口和多种折扣策略类(如 `FidelityDiscount`、`BulkDiscount` 和 `NoDiscount`),在运行时动态切换不同的折扣逻辑。这样,`ShoppingCart` 类无需关心具体折扣计算细节,只需设置不同的策略即可实现灵活的价格计算,符合开闭原则并提高代码的可维护性和扩展性。
61 2
|
3月前
|
安全 算法 Java
java系列之~~网络通信安全 非对称加密算法的介绍说明
这篇文章介绍了非对称加密算法,包括其定义、加密解密过程、数字签名功能,以及与对称加密算法的比较,并解释了非对称加密在网络安全中的应用,特别是在公钥基础设施和信任网络中的重要性。
|
3月前
|
数据采集 搜索推荐 算法
【高手进阶】Java排序算法:从零到精通——揭秘冒泡、快速、归并排序的原理与实战应用,让你的代码效率飙升!
【8月更文挑战第21天】Java排序算法是编程基础的重要部分,在算法设计与分析及实际开发中不可或缺。本文介绍内部排序算法,包括简单的冒泡排序及其逐步优化至高效的快速排序和稳定的归并排序,并提供了每种算法的Java实现示例。此外,还探讨了排序算法在电子商务、搜索引擎和数据分析等领域的广泛应用,帮助读者更好地理解和应用这些算法。
37 0