Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 287|回复: 0

[算法学习]DES加密算法源码(java版)

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-11-6 00:03:24 | 显示全部楼层 |阅读模式
    1. 来源:http://blog.csdn.net/zyg158/archive/2007/06/26/1667531.aspx
    2.                         
    3. public class DES {
    4.     // 声明常量字节数组
    5.     private static final int[] IP = {
    6.             58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54,
    7.             46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8, 57, 49, 41, 33,
    8.             25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3, 61, 53, 45, 37, 29, 21,
    9.             13, 5, 63, 55, 47, 39, 31, 23, 15, 7
    10.         }; // 64

    11.     private static final int[] IP_1 = {
    12.             40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31, 38, 6,
    13.             46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29, 36, 4, 44, 12,
    14.             52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27, 34, 2, 42, 10, 50, 18,
    15.             58, 26, 33, 1, 41, 9, 49, 17, 57, 25
    16.         }; // 64

    17.     private static final int[] PC_1 = {
    18.             57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51,
    19.             43, 35, 27, 19, 11, 3, 60, 52, 44, 36, 63, 55, 47, 39, 31, 23, 15, 7,
    20.             62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20,
    21.             12, 4
    22.         }; // 56

    23.     private static final int[] PC_2 = {
    24.             14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, 23, 19, 12, 4, 26, 8, 16,
    25.             7, 27, 20, 13, 2, 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48, 44,
    26.             49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32
    27.         }; // 48

    28.     private static final int[] E = {
    29.             32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12, 13, 12, 13,
    30.             14, 15, 16, 17, 16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25, 24,
    31.             25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1
    32.         }; // 48

    33.     private static final int[] P = {
    34.             16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, 2, 8,
    35.             24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25
    36.         }; // 32

    37.     private static final int[][][] S_Box = {
    38.             {
    39.                 { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7 },
    40.                 { 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8 },
    41.                 { 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0 },
    42.                 { 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 }
    43.             },
    44.             { // S_Box[1]
    45.                 { 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10 },
    46.                 { 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5 },
    47.                 { 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15 },
    48.                 { 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 }
    49.             },
    50.             { // S_Box[2]
    51.                 { 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8 },
    52.                 { 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1 },
    53.                 { 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7 },
    54.                 { 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 }
    55.             },
    56.             { // S_Box[3]
    57.                 { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15 },
    58.                 { 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9 },
    59.                 { 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4 },
    60.                 { 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 }
    61.             },
    62.             { // S_Box[4]
    63.                 { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9 },
    64.                 { 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6 },
    65.                 { 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14 },
    66.                 { 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 }
    67.             },
    68.             { // S_Box[5]
    69.                 { 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11 },
    70.                 { 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8 },
    71.                 { 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6 },
    72.                 { 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 }
    73.             },
    74.             { // S_Box[6]
    75.                 { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1 },
    76.                 { 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6 },
    77.                 { 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2 },
    78.                 { 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 }
    79.             },
    80.             { // S_Box[7]
    81.                 { 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7 },
    82.                 { 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2 },
    83.                 { 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8 },
    84.                 { 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 }
    85.             } // S_Box[8]
    86.         };

    87.     private static final int[] LeftMove = {
    88.             1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
    89.         }; // 左移位置列表

    90.     private byte[] UnitDes(byte[] des_key, byte[] des_data, int flag) {
    91.         // 检测输入参数格式是否正确,错误直接返回空值(null)
    92.         if ((des_key.length != 8) || (des_data.length != 8) ||
    93.                 ((flag != 1) && (flag != 0))) {
    94.             throw new RuntimeException("Data Format Error !");
    95.         }
    96.         int flags = flag;
    97.         // 二进制加密密钥
    98.         int[] keydata = new int[64];
    99.         // 二进制加密数据
    100.         int[] encryptdata = new int[64];
    101.         // 加密操作完成后的字节数组
    102.         byte[] EncryptCode = new byte[8];
    103.         // 密钥初试化成二维数组
    104.         int[][] KeyArray = new int[16][48];
    105.         // 将密钥字节数组转换成二进制字节数组
    106.         keydata = ReadDataToBirnaryIntArray(des_key);
    107.         // 将加密数据字节数组转换成二进制字节数组
    108.         encryptdata = ReadDataToBirnaryIntArray(des_data);
    109.         // 初试化密钥为二维密钥数组
    110.         KeyInitialize(keydata, KeyArray);
    111.         // 执行加密解密操作
    112.         EncryptCode = Encrypt(encryptdata, flags, KeyArray);
    113.         return EncryptCode;
    114.     }

    115.     // 初试化密钥数组
    116.     private void KeyInitialize(int[] key, int[][] keyarray) {
    117.         int i;
    118.         int j;
    119.         int[] K0 = new int[56];
    120.         // 特别注意:xxx[IP[i]-1]等类似变换
    121.         for (i = 0; i < 56; i++) {
    122.             K0[i] = key[PC_1[i] - 1]; // 密钥进行PC-1变换
    123.         }
    124.         for (i = 0; i < 16; i++) {
    125.             LeftBitMove(K0, LeftMove[i]);
    126.             // 特别注意:xxx[IP[i]-1]等类似变换
    127.             for (j = 0; j < 48; j++) {
    128.                 keyarray[i][j] = K0[PC_2[j] - 1]; // 生成子密钥keyarray[i][j]
    129.             }
    130.         }
    131.     }

    132.     // 执行加密解密操作
    133.     private byte[] Encrypt(int[] timeData, int flag, int[][] keyarray) {
    134.         int i;
    135.         byte[] encrypt = new byte[8];
    136.         int flags = flag;
    137.         int[] M = new int[64];
    138.         int[] MIP_1 = new int[64];
    139.         // 特别注意:xxx[IP[i]-1]等类似变换
    140.         for (i = 0; i < 64; i++) {
    141.             M[i] = timeData[IP[i] - 1]; // 明文IP变换
    142.         }
    143.         if (flags == 1) { // 加密
    144.             for (i = 0; i < 16; i++) {
    145.                 LoopF(M, i, flags, keyarray);
    146.             }
    147.         } else if (flags == 0) { // 解密
    148.             for (i = 15; i > -1; i--) {
    149.                 LoopF(M, i, flags, keyarray);
    150.             }
    151.         }
    152.         for (i = 0; i < 64; i++) {
    153.             MIP_1[i] = M[IP_1[i] - 1]; // 进行IP-1运算
    154.         }
    155.         GetEncryptResultOfByteArray(MIP_1, encrypt);
    156.         // 返回加密数据
    157.         return encrypt;
    158.     }

    159.     private int[] ReadDataToBirnaryIntArray(byte[] intdata) {
    160.         int i;
    161.         int j;
    162.         // 将数据转换为二进制数,存储到数组
    163.         int[] IntDa = new int[8];
    164.         for (i = 0; i < 8; i++) {
    165.             IntDa[i] = intdata[i];
    166.             if (IntDa[i] < 0) {
    167.                 IntDa[i] += 256;
    168.                 IntDa[i] %= 256;
    169.             }
    170.         }
    171.         int[] IntVa = new int[64];
    172.         for (i = 0; i < 8; i++) {
    173.             for (j = 0; j < 8; j++) {
    174.                 IntVa[((i * 8) + 7) - j] = IntDa[i] % 2;
    175.                 IntDa[i] = IntDa[i] / 2;
    176.             }
    177.         }
    178.         return IntVa;
    179.     }

    180.     private void LeftBitMove(int[] k, int offset) {
    181.         int i;
    182.         // 循环移位操作函数
    183.         int[] c0 = new int[28];
    184.         int[] d0 = new int[28];
    185.         int[] c1 = new int[28];
    186.         int[] d1 = new int[28];
    187.         for (i = 0; i < 28; i++) {
    188.             c0[i] = k[i];
    189.             d0[i] = k[i + 28];
    190.         }
    191.         if (offset == 1) {
    192.             for (i = 0; i < 27; i++) { // 循环左移一位
    193.                 c1[i] = c0[i + 1];
    194.                 d1[i] = d0[i + 1];
    195.             }
    196.             c1[27] = c0[0];
    197.             d1[27] = d0[0];
    198.         } else if (offset == 2) {
    199.             for (i = 0; i < 26; i++) { // 循环左移两位
    200.                 c1[i] = c0[i + 2];
    201.                 d1[i] = d0[i + 2];
    202.             }
    203.             c1[26] = c0[0];
    204.             d1[26] = d0[0];
    205.             c1[27] = c0[1];
    206.             d1[27] = d0[1];
    207.         }
    208.         for (i = 0; i < 28; i++) {
    209.             k[i] = c1[i];
    210.             k[i + 28] = d1[i];
    211.         }
    212.     }

    213.     private void LoopF(int[] M, int times, int flag, int[][] keyarray) {
    214.         int i;
    215.         int j;
    216.         int[] L0 = new int[32];
    217.         int[] R0 = new int[32];
    218.         int[] L1 = new int[32];
    219.         int[] R1 = new int[32];
    220.         int[] RE = new int[48];
    221.         int[][] S = new int[8][6];
    222.         int[] sBoxData = new int[8];
    223.         int[] sValue = new int[32];
    224.         int[] RP = new int[32];
    225.         for (i = 0; i < 32; i++) {
    226.             L0[i] = M[i]; // 明文左侧的初始化
    227.             R0[i] = M[i + 32]; // 明文右侧的初始化
    228.         }
    229.         for (i = 0; i < 48; i++) {
    230.             RE[i] = R0[E[i] - 1]; // 经过E变换扩充,由32位变为48位
    231.             RE[i] = RE[i] + keyarray[times][i]; // 与KeyArray[times][i]按位作不进位加法运算
    232.             if (RE[i] == 2) {
    233.                 RE[i] = 0;
    234.             }
    235.         }
    236.         for (i = 0; i < 8; i++) { // 48位分成8组
    237.             for (j = 0; j < 6; j++) {
    238.                 S[i][j] = RE[(i * 6) + j];
    239.             }
    240.             // 下面经过S盒,得到8个数
    241.             sBoxData[i] = S_Box[i][(S[i][0] << 1) + S[i][5]][(S[i][1] << 3) +
    242.                 (S[i][2] << 2) + (S[i][3] << 1) + S[i][4]];
    243.             // 8个数变换输出二进制
    244.             for (j = 0; j < 4; j++) {
    245.                 sValue[((i * 4) + 3) - j] = sBoxData[i] % 2;
    246.                 sBoxData[i] = sBoxData[i] / 2;
    247.             }
    248.         }
    249.         for (i = 0; i < 32; i++) {
    250.             RP[i] = sValue[P[i] - 1]; // 经过P变换
    251.             L1[i] = R0[i]; // 右边移到左边
    252.             R1[i] = L0[i] + RP[i];
    253.             if (R1[i] == 2) {
    254.                 R1[i] = 0;
    255.             }
    256.             // 重新合成M,返回数组M
    257.             // 最后一次变换时,左右不进行互换。此处采用两次变换实现不变
    258.             if (((flag == 0) && (times == 0)) ||
    259.                     ((flag == 1) && (times == 15))) {
    260.                 M[i] = R1[i];
    261.                 M[i + 32] = L1[i];
    262.             } else {
    263.                 M[i] = L1[i];
    264.                 M[i + 32] = R1[i];
    265.             }
    266.         }
    267.     }

    268.     private void GetEncryptResultOfByteArray(int[] data, byte[] value) {
    269.         int i;
    270.         int j;
    271.         // 将存储64位二进制数据的数组中的数据转换为八个整数(byte)
    272.         for (i = 0; i < 8; i++) {
    273.             for (j = 0; j < 8; j++) {
    274.                 value[i] += (data[(i << 3) + j] << (7 - j));
    275.             }
    276.         }
    277.         for (i = 0; i < 8; i++) {
    278.             value[i] %= 256;
    279.             if (value[i] > 128) {
    280.                 value[i] -= 255;
    281.             }
    282.         }
    283.     }

    284.     private byte[] ByteDataFormat(byte[] data) {
    285.         int len = data.length;
    286.         int padlen = 8 - (len % 8);
    287.         int newlen = len + padlen;
    288.         byte[] newdata = new byte[newlen];
    289.         System.arraycopy(data, 0, newdata, 0, len);
    290.         for (int i = len; i < newlen; i++)
    291.             newdata[i] = (byte) padlen;
    292.         return newdata;
    293.     }

    294.     public byte[] DesEncrypt(byte[] des_key, byte[] des_data, int flag) {
    295.         byte[] format_key = ByteDataFormat(des_key);
    296.         byte[] format_data = ByteDataFormat(des_data);
    297.         int datalen = format_data.length;
    298.         int unitcount = datalen / 8;
    299.         byte[] result_data = new byte[datalen];
    300.         for (int i = 0; i < unitcount; i++) {
    301.             byte[] tmpkey = new byte[8];
    302.             byte[] tmpdata = new byte[8];
    303.             System.arraycopy(format_key, 0, tmpkey, 0, 8);
    304.             System.arraycopy(format_data, i * 8, tmpdata, 0, 8);
    305.             byte[] tmpresult = UnitDes(tmpkey, tmpdata, flag);
    306.             System.arraycopy(tmpresult, 0, result_data, i * 8, 8);
    307.         }
    308.         return result_data;
    309.     }
    310.     public static void main(String[] args) {
    311.         String key = "00000000";
    312.         String data = "11111111";
    313.         int bytelen = data.getBytes().length;
    314.         byte[] result = new byte[(bytelen + 8) - (bytelen % 8)];
    315.         byte[] bytekey = key.getBytes();
    316.         byte[] bytedata = data.getBytes();
    317.         for (int i = 0; i < bytedata.length; i++) {
    318.             System.out.print(" " + bytedata[i] + " ");
    319.         }
    320.         System.out.println();
    321.         DES des = new DES();
    322.         result = des.DesEncrypt(bytekey, bytedata, 1);
    323.         for (int i = 0; i < result.length; i++) {
    324.             System.out.print(" " + result[i] + " ");
    325.         }
    326.         System.out.println();
    327.         result = des.DesEncrypt(bytekey, result, 0);
    328.         for (int i = 0; i < result.length; i++) {
    329.             System.out.print(" " + result[i] + " ");
    330.         }
    331.         System.out.println();
    332.     }
    333. }
    复制代码
    运行结果:
    C:        est>java DES
    49 49 49 49 49 49 49 49
    101 94 -90 40 -49 98 88 95 -83 106 -120 -76 -6 55 -125 61
    49 49 49 49 49 49 49 49 8 8 8 8 8 8 8 8 77 58 42 -24 39 90 119 121 C:        est>
       
         
         
          
          

            
          

            
          
         
       

      


    源码下载:http://file.javaxxz.com/2014/11/6/000324156.zip
    回复

    使用道具 举报

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

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-25 10:49 , Processed in 0.351007 second(s), 36 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

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