扎心了

package com.datacloudcsec.base.common.utils;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.charset.Charset;
import java.util.Random;

public class GrantIUtils {


    int serial_num_len = 19;

    public static int LIC_MODULE_NULL = 0,
            LIC_MODULE_TYPE = 1,
            LIC_MODULE_IPFLOW = 2,
            LIC_MODULE_VENGINE = 3,
            LIC_MODULE_ELEC_NIC_NUM = 4,
            LIC_MODULE_FIBER_NIC_NUM = 5,
            LIC_MODULE_SQL_INJECT = 6,
            LIC_MODULE_LINK_PORT_NUM = 7,
            LIC_MODULE_LINK_FIBER_NUM = 8,
            LIC_MODULE_HTTPS = 9,
            LIC_MODULE_ACCELERATE = 10,
            LIC_MODULE_IPCHECK = 11,
            LIC_MODULE_WEBSITE_TAKEOVER = 12,

    LIC_MODULE_MAX = 32;
    int[] ips_lic_id_len = {3, 3, 3, 3, 3, 3, 3, 3};
    int[] dba_lic_id_len = {0, 0, 3};

    long[][] des_skb =

            {
                    {
                            /* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
                            0x00000000, 0x00000010, 0x20000000, 0x20000010,
                            0x00010000, 0x00010010, 0x20010000, 0x20010010,
                            0x00000800, 0x00000810, 0x20000800, 0x20000810,
                            0x00010800, 0x00010810, 0x20010800, 0x20010810,
                            0x00000020, 0x00000030, 0x20000020, 0x20000030,
                            0x00010020, 0x00010030, 0x20010020, 0x20010030,
                            0x00000820, 0x00000830, 0x20000820, 0x20000830,
                            0x00010820, 0x00010830, 0x20010820, 0x20010830,
                            0x00080000, 0x00080010, 0x20080000, 0x20080010,
                            0x00090000, 0x00090010, 0x20090000, 0x20090010,
                            0x00080800, 0x00080810, 0x20080800, 0x20080810,
                            0x00090800, 0x00090810, 0x20090800, 0x20090810,
                            0x00080020, 0x00080030, 0x20080020, 0x20080030,
                            0x00090020, 0x00090030, 0x20090020, 0x20090030,
                            0x00080820, 0x00080830, 0x20080820, 0x20080830,
                            0x00090820, 0x00090830, 0x20090820, 0x20090830,
                    },
                    {
                            /* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
                            0x00000000, 0x02000000, 0x00002000, 0x02002000,
                            0x00200000, 0x02200000, 0x00202000, 0x02202000,
                            0x00000004, 0x02000004, 0x00002004, 0x02002004,
                            0x00200004, 0x02200004, 0x00202004, 0x02202004,
                            0x00000400, 0x02000400, 0x00002400, 0x02002400,
                            0x00200400, 0x02200400, 0x00202400, 0x02202400,
                            0x00000404, 0x02000404, 0x00002404, 0x02002404,
                            0x00200404, 0x02200404, 0x00202404, 0x02202404,
                            0x10000000, 0x12000000, 0x10002000, 0x12002000,
                            0x10200000, 0x12200000, 0x10202000, 0x12202000,
                            0x10000004, 0x12000004, 0x10002004, 0x12002004,
                            0x10200004, 0x12200004, 0x10202004, 0x12202004,
                            0x10000400, 0x12000400, 0x10002400, 0x12002400,
                            0x10200400, 0x12200400, 0x10202400, 0x12202400,
                            0x10000404, 0x12000404, 0x10002404, 0x12002404,
                            0x10200404, 0x12200404, 0x10202404, 0x12202404,
                    },
                    {
                            /* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
                            0x00000000, 0x00000001, 0x00040000, 0x00040001,
                            0x01000000, 0x01000001, 0x01040000, 0x01040001,
                            0x00000002, 0x00000003, 0x00040002, 0x00040003,
                            0x01000002, 0x01000003, 0x01040002, 0x01040003,
                            0x00000200, 0x00000201, 0x00040200, 0x00040201,
                            0x01000200, 0x01000201, 0x01040200, 0x01040201,
                            0x00000202, 0x00000203, 0x00040202, 0x00040203,
                            0x01000202, 0x01000203, 0x01040202, 0x01040203,
                            0x08000000, 0x08000001, 0x08040000, 0x08040001,
                            0x09000000, 0x09000001, 0x09040000, 0x09040001,
                            0x08000002, 0x08000003, 0x08040002, 0x08040003,
                            0x09000002, 0x09000003, 0x09040002, 0x09040003,
                            0x08000200, 0x08000201, 0x08040200, 0x08040201,
                            0x09000200, 0x09000201, 0x09040200, 0x09040201,
                            0x08000202, 0x08000203, 0x08040202, 0x08040203,
                            0x09000202, 0x09000203, 0x09040202, 0x09040203,
                    },
                    {
                            /* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
                            0x00000000, 0x00100000, 0x00000100, 0x00100100,
                            0x00000008, 0x00100008, 0x00000108, 0x00100108,
                            0x00001000, 0x00101000, 0x00001100, 0x00101100,
                            0x00001008, 0x00101008, 0x00001108, 0x00101108,
                            0x04000000, 0x04100000, 0x04000100, 0x04100100,
                            0x04000008, 0x04100008, 0x04000108, 0x04100108,
                            0x04001000, 0x04101000, 0x04001100, 0x04101100,
                            0x04001008, 0x04101008, 0x04001108, 0x04101108,
                            0x00020000, 0x00120000, 0x00020100, 0x00120100,
                            0x00020008, 0x00120008, 0x00020108, 0x00120108,
                            0x00021000, 0x00121000, 0x00021100, 0x00121100,
                            0x00021008, 0x00121008, 0x00021108, 0x00121108,
                            0x04020000, 0x04120000, 0x04020100, 0x04120100,
                            0x04020008, 0x04120008, 0x04020108, 0x04120108,
                            0x04021000, 0x04121000, 0x04021100, 0x04121100,
                            0x04021008, 0x04121008, 0x04021108, 0x04121108,
                    },
                    {
                            /* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
                            0x00000000, 0x10000000, 0x00010000, 0x10010000,
                            0x00000004, 0x10000004, 0x00010004, 0x10010004,
                            0x20000000, 0x30000000, 0x20010000, 0x30010000,
                            0x20000004, 0x30000004, 0x20010004, 0x30010004,
                            0x00100000, 0x10100000, 0x00110000, 0x10110000,
                            0x00100004, 0x10100004, 0x00110004, 0x10110004,
                            0x20100000, 0x30100000, 0x20110000, 0x30110000,
                            0x20100004, 0x30100004, 0x20110004, 0x30110004,
                            0x00001000, 0x10001000, 0x00011000, 0x10011000,
                            0x00001004, 0x10001004, 0x00011004, 0x10011004,
                            0x20001000, 0x30001000, 0x20011000, 0x30011000,
                            0x20001004, 0x30001004, 0x20011004, 0x30011004,
                            0x00101000, 0x10101000, 0x00111000, 0x10111000,
                            0x00101004, 0x10101004, 0x00111004, 0x10111004,
                            0x20101000, 0x30101000, 0x20111000, 0x30111000,
                            0x20101004, 0x30101004, 0x20111004, 0x30111004,
                    },
                    {
                            /* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
                            0x00000000, 0x08000000, 0x00000008, 0x08000008,
                            0x00000400, 0x08000400, 0x00000408, 0x08000408,
                            0x00020000, 0x08020000, 0x00020008, 0x08020008,
                            0x00020400, 0x08020400, 0x00020408, 0x08020408,
                            0x00000001, 0x08000001, 0x00000009, 0x08000009,
                            0x00000401, 0x08000401, 0x00000409, 0x08000409,
                            0x00020001, 0x08020001, 0x00020009, 0x08020009,
                            0x00020401, 0x08020401, 0x00020409, 0x08020409,
                            0x02000000, 0x0A000000, 0x02000008, 0x0A000008,
                            0x02000400, 0x0A000400, 0x02000408, 0x0A000408,
                            0x02020000, 0x0A020000, 0x02020008, 0x0A020008,
                            0x02020400, 0x0A020400, 0x02020408, 0x0A020408,
                            0x02000001, 0x0A000001, 0x02000009, 0x0A000009,
                            0x02000401, 0x0A000401, 0x02000409, 0x0A000409,
                            0x02020001, 0x0A020001, 0x02020009, 0x0A020009,
                            0x02020401, 0x0A020401, 0x02020409, 0x0A020409,
                    },
                    {
                            /* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
                            0x00000000, 0x00000100, 0x00080000, 0x00080100,
                            0x01000000, 0x01000100, 0x01080000, 0x01080100,
                            0x00000010, 0x00000110, 0x00080010, 0x00080110,
                            0x01000010, 0x01000110, 0x01080010, 0x01080110,
                            0x00200000, 0x00200100, 0x00280000, 0x00280100,
                            0x01200000, 0x01200100, 0x01280000, 0x01280100,
                            0x00200010, 0x00200110, 0x00280010, 0x00280110,
                            0x01200010, 0x01200110, 0x01280010, 0x01280110,
                            0x00000200, 0x00000300, 0x00080200, 0x00080300,
                            0x01000200, 0x01000300, 0x01080200, 0x01080300,
                            0x00000210, 0x00000310, 0x00080210, 0x00080310,
                            0x01000210, 0x01000310, 0x01080210, 0x01080310,
                            0x00200200, 0x00200300, 0x00280200, 0x00280300,
                            0x01200200, 0x01200300, 0x01280200, 0x01280300,
                            0x00200210, 0x00200310, 0x00280210, 0x00280310,
                            0x01200210, 0x01200310, 0x01280210, 0x01280310,
                    },
                    {
                            /* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
                            0x00000000, 0x04000000, 0x00040000, 0x04040000,
                            0x00000002, 0x04000002, 0x00040002, 0x04040002,
                            0x00002000, 0x04002000, 0x00042000, 0x04042000,
                            0x00002002, 0x04002002, 0x00042002, 0x04042002,
                            0x00000020, 0x04000020, 0x00040020, 0x04040020,
                            0x00000022, 0x04000022, 0x00040022, 0x04040022,
                            0x00002020, 0x04002020, 0x00042020, 0x04042020,
                            0x00002022, 0x04002022, 0x00042022, 0x04042022,
                            0x00000800, 0x04000800, 0x00040800, 0x04040800,
                            0x00000802, 0x04000802, 0x00040802, 0x04040802,
                            0x00002800, 0x04002800, 0x00042800, 0x04042800,
                            0x00002802, 0x04002802, 0x00042802, 0x04042802,
                            0x00000820, 0x04000820, 0x00040820, 0x04040820,
                            0x00000822, 0x04000822, 0x00040822, 0x04040822,
                            0x00002820, 0x04002820, 0x00042820, 0x04042820,
                            0x00002822, 0x04002822, 0x00042822, 0x04042822,
                    }
            };

    long[][] des_sptrans =

            {
                    {
                            /* nibble 0 */
                            0x02080800, 0x00080000, 0x02000002, 0x02080802,
                            0x02000000, 0x00080802, 0x00080002, 0x02000002,
                            0x00080802, 0x02080800, 0x02080000, 0x00000802,
                            0x02000802, 0x02000000, 0x00000000, 0x00080002,
                            0x00080000, 0x00000002, 0x02000800, 0x00080800,
                            0x02080802, 0x02080000, 0x00000802, 0x02000800,
                            0x00000002, 0x00000800, 0x00080800, 0x02080002,
                            0x00000800, 0x02000802, 0x02080002, 0x00000000,
                            0x00000000, 0x02080802, 0x02000800, 0x00080002,
                            0x02080800, 0x00080000, 0x00000802, 0x02000800,
                            0x02080002, 0x00000800, 0x00080800, 0x02000002,
                            0x00080802, 0x00000002, 0x02000002, 0x02080000,
                            0x02080802, 0x00080800, 0x02080000, 0x02000802,
                            0x02000000, 0x00000802, 0x00080002, 0x00000000,
                            0x00080000, 0x02000000, 0x02000802, 0x02080800,
                            0x00000002, 0x02080002, 0x00000800, 0x00080802,
                    },
                    {
                            /* nibble 1 */
                            0x40108010, 0x00000000, 0x00108000, 0x40100000,
                            0x40000010, 0x00008010, 0x40008000, 0x00108000,
                            0x00008000, 0x40100010, 0x00000010, 0x40008000,
                            0x00100010, 0x40108000, 0x40100000, 0x00000010,
                            0x00100000, 0x40008010, 0x40100010, 0x00008000,
                            0x00108010, 0x40000000, 0x00000000, 0x00100010,
                            0x40008010, 0x00108010, 0x40108000, 0x40000010,
                            0x40000000, 0x00100000, 0x00008010, 0x40108010,
                            0x00100010, 0x40108000, 0x40008000, 0x00108010,
                            0x40108010, 0x00100010, 0x40000010, 0x00000000,
                            0x40000000, 0x00008010, 0x00100000, 0x40100010,
                            0x00008000, 0x40000000, 0x00108010, 0x40008010,
                            0x40108000, 0x00008000, 0x00000000, 0x40000010,
                            0x00000010, 0x40108010, 0x00108000, 0x40100000,
                            0x40100010, 0x00100000, 0x00008010, 0x40008000,
                            0x40008010, 0x00000010, 0x40100000, 0x00108000,
                    },
                    {
                            /* nibble 2 */
                            0x04000001, 0x04040100, 0x00000100, 0x04000101,
                            0x00040001, 0x04000000, 0x04000101, 0x00040100,
                            0x04000100, 0x00040000, 0x04040000, 0x00000001,
                            0x04040101, 0x00000101, 0x00000001, 0x04040001,
                            0x00000000, 0x00040001, 0x04040100, 0x00000100,
                            0x00000101, 0x04040101, 0x00040000, 0x04000001,
                            0x04040001, 0x04000100, 0x00040101, 0x04040000,
                            0x00040100, 0x00000000, 0x04000000, 0x00040101,
                            0x04040100, 0x00000100, 0x00000001, 0x00040000,
                            0x00000101, 0x00040001, 0x04040000, 0x04000101,
                            0x00000000, 0x04040100, 0x00040100, 0x04040001,
                            0x00040001, 0x04000000, 0x04040101, 0x00000001,
                            0x00040101, 0x04000001, 0x04000000, 0x04040101,
                            0x00040000, 0x04000100, 0x04000101, 0x00040100,
                            0x04000100, 0x00000000, 0x04040001, 0x00000101,
                            0x04000001, 0x00040101, 0x00000100, 0x04040000,
                    },
                    {
                            /* nibble 3 */
                            0x00401008, 0x10001000, 0x00000008, 0x10401008,
                            0x00000000, 0x10400000, 0x10001008, 0x00400008,
                            0x10401000, 0x10000008, 0x10000000, 0x00001008,
                            0x10000008, 0x00401008, 0x00400000, 0x10000000,
                            0x10400008, 0x00401000, 0x00001000, 0x00000008,
                            0x00401000, 0x10001008, 0x10400000, 0x00001000,
                            0x00001008, 0x00000000, 0x00400008, 0x10401000,
                            0x10001000, 0x10400008, 0x10401008, 0x00400000,
                            0x10400008, 0x00001008, 0x00400000, 0x10000008,
                            0x00401000, 0x10001000, 0x00000008, 0x10400000,
                            0x10001008, 0x00000000, 0x00001000, 0x00400008,
                            0x00000000, 0x10400008, 0x10401000, 0x00001000,
                            0x10000000, 0x10401008, 0x00401008, 0x00400000,
                            0x10401008, 0x00000008, 0x10001000, 0x00401008,
                            0x00400008, 0x00401000, 0x10400000, 0x10001008,
                            0x00001008, 0x10000000, 0x10000008, 0x10401000,
                    },
                    {
                            /* nibble 4 */
                            0x08000000, 0x00010000, 0x00000400, 0x08010420,
                            0x08010020, 0x08000400, 0x00010420, 0x08010000,
                            0x00010000, 0x00000020, 0x08000020, 0x00010400,
                            0x08000420, 0x08010020, 0x08010400, 0x00000000,
                            0x00010400, 0x08000000, 0x00010020, 0x00000420,
                            0x08000400, 0x00010420, 0x00000000, 0x08000020,
                            0x00000020, 0x08000420, 0x08010420, 0x00010020,
                            0x08010000, 0x00000400, 0x00000420, 0x08010400,
                            0x08010400, 0x08000420, 0x00010020, 0x08010000,
                            0x00010000, 0x00000020, 0x08000020, 0x08000400,
                            0x08000000, 0x00010400, 0x08010420, 0x00000000,
                            0x00010420, 0x08000000, 0x00000400, 0x00010020,
                            0x08000420, 0x00000400, 0x00000000, 0x08010420,
                            0x08010020, 0x08010400, 0x00000420, 0x00010000,
                            0x00010400, 0x08010020, 0x08000400, 0x00000420,
                            0x00000020, 0x00010420, 0x08010000, 0x08000020,
                    },
                    {
                            /* nibble 5 */
                            0x80000040, 0x00200040, 0x00000000, 0x80202000,
                            0x00200040, 0x00002000, 0x80002040, 0x00200000,
                            0x00002040, 0x80202040, 0x00202000, 0x80000000,
                            0x80002000, 0x80000040, 0x80200000, 0x00202040,
                            0x00200000, 0x80002040, 0x80200040, 0x00000000,
                            0x00002000, 0x00000040, 0x80202000, 0x80200040,
                            0x80202040, 0x80200000, 0x80000000, 0x00002040,
                            0x00000040, 0x00202000, 0x00202040, 0x80002000,
                            0x00002040, 0x80000000, 0x80002000, 0x00202040,
                            0x80202000, 0x00200040, 0x00000000, 0x80002000,
                            0x80000000, 0x00002000, 0x80200040, 0x00200000,
                            0x00200040, 0x80202040, 0x00202000, 0x00000040,
                            0x80202040, 0x00202000, 0x00200000, 0x80002040,
                            0x80000040, 0x80200000, 0x00202040, 0x00000000,
                            0x00002000, 0x80000040, 0x80002040, 0x80202000,
                            0x80200000, 0x00002040, 0x00000040, 0x80200040,
                    },
                    {
                            /* nibble 6 */
                            0x00004000, 0x00000200, 0x01000200, 0x01000004,
                            0x01004204, 0x00004004, 0x00004200, 0x00000000,
                            0x01000000, 0x01000204, 0x00000204, 0x01004000,
                            0x00000004, 0x01004200, 0x01004000, 0x00000204,
                            0x01000204, 0x00004000, 0x00004004, 0x01004204,
                            0x00000000, 0x01000200, 0x01000004, 0x00004200,
                            0x01004004, 0x00004204, 0x01004200, 0x00000004,
                            0x00004204, 0x01004004, 0x00000200, 0x01000000,
                            0x00004204, 0x01004000, 0x01004004, 0x00000204,
                            0x00004000, 0x00000200, 0x01000000, 0x01004004,
                            0x01000204, 0x00004204, 0x00004200, 0x00000000,
                            0x00000200, 0x01000004, 0x00000004, 0x01000200,
                            0x00000000, 0x01000204, 0x01000200, 0x00004200,
                            0x00000204, 0x00004000, 0x01004204, 0x01000000,
                            0x01004200, 0x00000004, 0x00004004, 0x01004204,
                            0x01000004, 0x01004200, 0x01004000, 0x00004004,
                    },
                    {
                            /* nibble 7 */
                            0x20800080, 0x20820000, 0x00020080, 0x00000000,
                            0x20020000, 0x00800080, 0x20800000, 0x20820080,
                            0x00000080, 0x20000000, 0x00820000, 0x00020080,
                            0x00820080, 0x20020080, 0x20000080, 0x20800000,
                            0x00020000, 0x00820080, 0x00800080, 0x20020000,
                            0x20820080, 0x20000080, 0x00000000, 0x00820000,
                            0x20000000, 0x00800000, 0x20020080, 0x20800080,
                            0x00800000, 0x00020000, 0x20820000, 0x00000080,
                            0x00800000, 0x00020000, 0x20000080, 0x20820080,
                            0x00020080, 0x20000000, 0x00000000, 0x00820000,
                            0x20800080, 0x20020080, 0x20020000, 0x00800080,
                            0x20820000, 0x00000080, 0x00800080, 0x20020000,
                            0x20820080, 0x00800000, 0x20800000, 0x20000080,
                            0x00820000, 0x00020080, 0x20020080, 0x20800000,
                            0x00000080, 0x20820000, 0x00820080, 0x00000000,
                            0x20000000, 0x20800080, 0x00020000, 0x00820080,
                    }
            };

    int MAX_LIC_LEN = 512;
    int ITERATIONS = 16;
    byte[] license_key = "datacsec".getBytes( Charset.forName( "utf-8" ) );
    byte[] license_iv = "cloudlic".getBytes( Charset.forName( "utf-8" ) );
    long[] schedule = new long[32];

    public static long longToint(long n) {
        return n & 0x00000000ffffffffl;
//        return (n << 32) >>> 32;
    }


    long ROTATE(long a, int n) {
        a = longToint( a );
        long ret = 0;
        ret = longToint( longToint( (a >> n) ) + longToint( a << (32 - n) ) );
        return ret;
    }


    String l2c(long l, String str) {
        l = longToint( l );
//    void l2c(uint l, ref string str) {
        str += (char)( l & 0xff );
        str += (char)( longToint( l >> 8 ) & 0xff );
        str += (char)( longToint( l >> 16 ) & 0xff );
        str += (char)( longToint( l >> 24 ) & 0xff );
        return str;
    }


    String l2cn(long a, long b, String str, int n) {
        a = longToint( a );
        b = longToint( b );
        for (int i = 0; i < n; i++) {
            switch (i) {
                case 1:
                    str += (char) (longToint( a ) & 0xff);
                    break;
                case 2:
                    str += (char) (longToint( a >> 8 ) & 0xff);
                    break;
                case 3:
                    str += (char) (longToint( a >> 16 ) & 0xff);
                    break;
                case 4:
                    str += (char) (longToint( a >> 24 ) & 0xff);
                    break;
                case 5:
                    str += (char) (b & 0xff);
                    break;
                case 6:
                    str += (char) (longToint( b >> 8 ) & 0xff);
                    break;
                case 7:
                    str += (char) (longToint( b >> 16 ) & 0xff);
                    break;
                case 8:
                    str += (char) (longToint( b >> 24 ) & 0xff);
                    break;
            }

        }
        return str;
    }

    String des_ncbc_encrypt(char[] license, int type) {
        long a, b, c, d, m, n;
        long[] tin = new long[2];
        String enc_lic = "";
        int l = license.length;
        int lic_index = 0;

        a = b = c = d = m = n = 0;

        if (type == 1) {
            int iv_index = 0;
///
//            b2l( ref license_iv, ref iv_index, ref c );
//            b2l( ref license_iv, ref iv_index, ref d );

            B21 b21 = new B21( license_iv, iv_index, c ).invoke();
            c = b21.getC();
            iv_index = b21.getIv_index();
            license_iv = b21.getLience();

            B21 b22 = new B21( license_iv, iv_index, c ).invoke();
            d = b22.getC();
            license_iv = b22.getLience();
            iv_index = b22.getIv_index();
            /-------------
            for (l -= 8; l >= 0; l -= 8) {
//                c2l( ref license, ref lic_index, ref a );
//                c2l( ref license, ref lic_index, ref b );
                C21 c21 = new C21( license, lic_index, a ).invoke();
                a = c21.getB();
                license = c21.getLicense();
                lic_index = c21.getLic_index();

                C21 c211 = new C21( license, lic_index, b ).invoke();
                b = c211.getB();
                license = c211.getLicense();
                lic_index = c211.getLic_index();
                //-------------///
                a = longToint( a ^ c );
                tin[0] = longToint( a );
                b = longToint( b ^ d );
                tin[1] = longToint( b );
//
                //                des_encrypt( ref tin, type );
                tin = des_encrypt( type, tin );

/
                c = longToint( tin[0] );
                enc_lic = l2c( c, enc_lic );

                d = longToint( tin[1] );
                enc_lic = l2c( d, enc_lic );
            }

            if (l != -8) {
                //-------------------//
//                c2ln( ref license, lic_index, ref a, ref b, l + 8 );
                //    void c2ln(ref string str, int index, ref uint a, ref uint b, int n) {
//                void c2ln(char[] str, int index, long a1, long b1, int n1) {
                C2ln c2ln = new C2ln( license, longToint( a ), longToint( b ), l, lic_index ).invoke();
                license = c2ln.getLicense();
                a = c2ln.getA();
                b = c2ln.getB();
//                }
                //-------------------///
                a = longToint( a ^ c );
                tin[0] = longToint( a );
                b = longToint( b ^ d );
                tin[1] = longToint( b );

//                des_encrypt( (ref[]) ref( int)(int) tin, (int) type );
                tin = des_encrypt( type, tin );
                c = tin[0];
                enc_lic = l2c( c, enc_lic );

                d = tin[1];
                enc_lic = l2c( d, enc_lic );
            }
        } else {
//            b2l( ref license_iv, ref lic_index, ref m );
            B21 b21 = new B21( license_iv, lic_index, m ).invoke();
            m = b21.getC();
            lic_index = b21.getIv_index();
            license_iv = b21.getLience();

//            b2l( ref license_iv, ref lic_index, ref n );

            B21 b22 = new B21( license_iv, lic_index, n ).invoke();
            n = b22.getC();
            lic_index = b22.getIv_index();
            license_iv = b22.getLience();

            for (l -= 8; l >= 0; l -= 8) {
//                c2l( ref license, ref lic_index, ref a );
                C21 c21 = new C21( license, lic_index, a ).invoke();
                a = c21.getB();
                license = c21.getLicense();
                lic_index = c21.getLic_index();
                tin[0] = a;

//                c2l( ref license, ref lic_index, ref b );
                C21 c22 = new C21( license, lic_index, b ).invoke();
                a = c22.getB();
                license = c22.getLicense();
                lic_index = c22.getLic_index();
                tin[1] = b;

//                des_encrypt( (ref[]) ref( int)(int) tin, (int) type );
                tin = des_encrypt( type, tin );
                c = tin[0] ^ m;
                d = tin[1] ^ n;

//                l2c( c, ref enc_lic );
//                l2c( d, ref enc_lic );
                enc_lic = l2c( c, enc_lic );
                enc_lic = l2c( d, enc_lic );

                m = a;
                n = b;
            }

            if (l != -8) {
//                c2l( ref license, ref lic_index, ref a );
                C21 c21 = new C21( license, lic_index, a ).invoke();
                a = c21.getB();
                license = c21.getLicense();
                lic_index = c21.getLic_index();
                tin[0] = a;

//                c2l( ref license, ref lic_index, ref b );
                C21 c22 = new C21( license, lic_index, b ).invoke();
                b = c22.getB();
                license = c22.getLicense();
                lic_index = c22.getLic_index();

                tin[1] = longToint( b );
//                des_encrypt( (ref[]) ref( int)(int) tin, (int) type );
                c = longToint( tin[0] ^ m );
                tin = des_encrypt( type, tin );

                d = longToint( tin[1] ^ n );
                enc_lic = l2cn( c, d, enc_lic, l + 8 );

                m = a;
                n = b;
            }
        }

        return enc_lic;
    }

    private long[] des_encrypt(int type, long[] tin) {
        //                des_encrypt( ref tin, type );
        long r = longToint( tin[0] );
        long l = longToint( tin[1] );
        long a = 0;
        long b = 0;
        //-----------------------//
//                IP( ref r, ref l );

        long tt = 0;
        //----------------------//
        /*uint tt = 0;
        PERM_OP(ref r, ref l, ref tt, 4, 0x0f0f0f0f);
        PERM_OP(ref l, ref r, ref tt, 16, 0x0000ffff);
        PERM_OP(ref r, ref l, ref tt, 2, 0x33333333);
        PERM_OP(ref l, ref r, ref tt, 8, 0x00ff00ff);
        PERM_OP(ref r, ref l, ref tt, 1, 0x55555555);*/
//                void PERM_OP(ref uint a, ref uint b, ref uint t, int n, uint m) {
        PERM_OP PERM_OP = new PERM_OP( longToint( l ), longToint( r ), longToint( tt ), 4, longToint( 0x0f0f0f0f ) ).invoke();
        l = PERM_OP.getR();
        r = PERM_OP.getL();
        tt = PERM_OP.getTt();

        GrantIUtils.PERM_OP PERM_OP1 = new PERM_OP( longToint( r ), longToint( l ), longToint( tt ), 16, longToint( 0x0000ffff ) ).invoke();
        r = PERM_OP1.getR();
        l = PERM_OP1.getL();
        tt = PERM_OP1.getTt();

        GrantIUtils.PERM_OP PERM_OP2 = new PERM_OP( longToint( l ), longToint( r ), longToint( tt ), 2, longToint( 0x33333333 ) ).invoke();
        l = PERM_OP2.getR();
        r = PERM_OP2.getL();
        tt = PERM_OP2.getTt();

        GrantIUtils.PERM_OP PERM_OP3 = new PERM_OP( longToint( r ), longToint( l ), longToint( tt ), 8, longToint( 0x00ff00ff ) ).invoke();
        r = PERM_OP3.getR();
        l = PERM_OP3.getL();
        tt = PERM_OP3.getTt();

        GrantIUtils.PERM_OP PERM_OP4 = new PERM_OP( longToint( l ), longToint( r ), longToint( tt ), 1, longToint( 0x55555555 ) ).invoke();
        l = PERM_OP4.getR();
        r = PERM_OP4.getL();
        tt = PERM_OP4.getTt();
//                }
        //----------------------//
        //----------------------//
        r = longToint( ROTATE( r, 29 ) & 0xffffffff );
        l = longToint( ROTATE( l, 29 ) & 0xffffffff );
        //---------------------//
        if (type == 1) {
            int j = 0;
            for (int i = 0; i <= 30; i += 2) {
//                void D_ENCRYPT(ref long l, ref long r, ref long u, ref long t, int s) {
                if (j % 2 == 0) {
                    D_ENCRYPT d_encrypt = new D_ENCRYPT( longToint( l ), longToint( r ), longToint( a ), longToint( b ), i ).invoke();
                    a = d_encrypt.getU();
                    r = d_encrypt.getR();
                    l = d_encrypt.getL();
                    b = d_encrypt.getT();
                } else {
                    D_ENCRYPT d_encrypt = new D_ENCRYPT( longToint( r ), longToint( l ), longToint( a ), longToint( b ), i ).invoke();
                    a = d_encrypt.getU();
                    l = d_encrypt.getR();
                    r = d_encrypt.getL();
                    b = d_encrypt.getT();
                }

                j++;
            }

        } else {

            int j = 0;
            for (int i = 30; i >= 0; i -= 2) {
//                void D_ENCRYPT(ref long l, ref long r, ref long u, ref long t, int s) {
                if (j % 2 == 0) {
                    D_ENCRYPT d_encrypt = new D_ENCRYPT( longToint( l ), longToint( r ), longToint( a ), longToint( b ), i ).invoke();
                    a = d_encrypt.getU();
                    r = d_encrypt.getR();
                    l = d_encrypt.getL();
                    b = d_encrypt.getT();
                } else {
                    D_ENCRYPT d_encrypt = new D_ENCRYPT( longToint( r ), longToint( l ), longToint( a ), longToint( b ), i ).invoke();
                    a = d_encrypt.getU();
                    l = d_encrypt.getR();
                    r = d_encrypt.getL();
                    b = d_encrypt.getT();
                }

                j++;
            }

        }
        //------------------------------//
        l = longToint( ROTATE( l, 3 ) & 0xffffffff );
        r = longToint( ROTATE( r, 3 ) & 0xffffffff );
        //----------------------//
//                FP( ref r, ref ll );
//        void FP(long l, long r)
        FP fp = new FP( longToint( l ), longToint( r ) ).invoke();
        l = fp.getR();
        r = fp.getLl();
        //---------------------//
        tin[0] = l;
        tin[1] = r;
        return tin;
    }

    long get_license_crc(char[] str) {
        long int_crc = 0;
        long cn_crc = 0x04C10DB7;
        long naccum = 0;
        long[] crc_table = new long[256];

        for (int i = 0; i < 256; i++) {
            long ndata = 0;
            ndata = longToint( i << 24 );
            naccum = 0;

            for (int j = 0; j < 8; j++) {
                if (((ndata ^ naccum) & 0x80000000) != 0) {
                    naccum = longToint( naccum << 1 ) ^ cn_crc;
                } else {
                    naccum = longToint( naccum << 1 );
                }

                ndata = longToint( ndata << 1 );
            }

            crc_table[i] = naccum;
        }

        int_crc = 0;

        for (int i = 0; i < str.length; i++) {
            int_crc = longToint( longToint( int_crc << 8 ) ^ longToint( crc_table[(int) longToint( longToint( int_crc >> 24 ) ^ str[i] )] ) );
        }

        int_crc %= 10000;

        return int_crc;
    }

    void get_scheduler() {
        int[] shifts2 = {0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0};
        int sch_index = 0;
        int i = 0;
        long c, d, t, s, t2;
        int key_index = 0;

        c = d = t = s = t2 = 0;

        for (i = 0; i < 32; i++) {
            schedule[i] = 0;
        }

//        b2l( ref license_key, ref key_index, ref c );
//        b2l( ref license_key, ref key_index, ref d );
        B21 b21 = new B21( license_key, key_index, c ).invoke();
        c = b21.getC();
        key_index = b21.getIv_index();
        license_key = b21.getLience();

        B21 b22 = new B21( license_key, key_index, d ).invoke();
        d = b22.getC();
        key_index = b22.getIv_index();
        license_key = b22.getLience();

        PERM_OP invoke = new PERM_OP( d, c, t, 4, 0x0f0f0f0f ).invoke();
        d = invoke.getR();
        c = invoke.getL();
        t = invoke.getTt();

        //-------------------------//
//        new HPERM_OP( ref c, ref t, -2, 0xcccc0000 ).invoke();
//        new HPERM_OP( ref d, ref t, -2, 0xcccc0000 ).invoke();
//        void HPERM_OP(long a, long t, int n, long m) {
        HPERM_OP HPERM_OP = new HPERM_OP( c, t, -2, longToint( 0xcccc0000 ) ).invoke();
        c = HPERM_OP.getC();
        t = HPERM_OP.getT();

        HPERM_OP HPERM_OP1 = new HPERM_OP( d, t, -2, longToint( 0xcccc0000 ) ).invoke();
        d = HPERM_OP1.getC();
        t = HPERM_OP1.getT();

//        }
        //--------------------------//
        PERM_OP invoke1 = new PERM_OP( d, c, t, 1, longToint( 0x55555555 ) ).invoke();
        d = invoke1.getR();
        c = invoke1.getL();
        t = invoke1.getTt();

        PERM_OP invoke2 = new PERM_OP( c, d, t, 8, longToint( 0x00ff00ff ) ).invoke();
        c = invoke2.getR();
        d = invoke2.getL();
        t = invoke2.getTt();

        PERM_OP invoke3 = new PERM_OP( d, c, t, 1, longToint( 0x55555555 ) ).invoke();
        d = invoke3.getR();
        c = invoke3.getL();
        t = invoke3.getTt();
        d = (((d & longToint( 0x000000ff )) << 16) | (d & longToint( 0x0000ff00 )) | ((d & longToint( 0x00ff0000 )) >> 16) | ((c & longToint( 0xf0000000 )) >> 4));
//        d = (((d & longToint(0x000000ff)) << 16) | (d & longToint(0x0000ff00)) | ((d & longToint(0x00ff0000)) >> 16) | ((c & longToint(0xf0000000)) >> 4));
        c = longToint( c & longToint( 0x0fffffff ) );

        for (i = 0; i < ITERATIONS; i++) {
            if (shifts2[i] != 0) {
                c = longToint( longToint( (c >> 2) ) | longToint( (c << 26) ) );
                d = longToint( (longToint( d >> 2 ) | longToint( d << 26 )) );
            } else {
                c = longToint( longToint( c >> 1 ) | longToint( c << 27 ) );
                d = longToint( longToint( d >> 1 ) | longToint( d << 27 ) );
            }

            c = longToint( c & longToint( 0x0fffffff ) );
            d = longToint( d & longToint( 0x0fffffff ) );
            s = longToint( des_skb[0][(int) longToint( (c) & 0x3f )] ) |
                    longToint( des_skb[1][(int) longToint( ((c >> 6) & 0x03) | ((c >> 7) & 0x3c) )] ) |
                    longToint( des_skb[2][(int) longToint( ((c >> 13) & 0x0f) | ((c >> 14) & 0x30) )] ) |
                    longToint( des_skb[3][(int) longToint( ((c >> 20) & 0x01) | ((c >> 21) & 0x06) | ((c >> 22) & 0x38) )] );

            t = longToint( longToint( des_skb[4][(int) longToint( (d) & 0x3f )] ) |
                    longToint( des_skb[5][(int) longToint( ((d >> 7) & 0x03) | ((d >> 8) & 0x3c) )] ) |
                    longToint( des_skb[6][(int) longToint( (d >> 15) & 0x3f )] )
                    | longToint( des_skb[7][(int) longToint( ((d >> 21) & 0x0f) | ((d >> 22) & 0x30) )] ) );

            t2 = longToint( ((t << 16) | (s & longToint( 0x0000ffff ))) & longToint( 0xffffffff ) );
            schedule[sch_index++] = longToint( longToint( ROTATE( t2, 30 ) ) & longToint( 0xffffffff ) );
            //str += schedule[sch_index - 1].ToString() + "\t";
            t2 = longToint( (longToint( s >> 16 ) | longToint( t & 0xffff0000 )) );
            schedule[sch_index++] = longToint( longToint( ROTATE( t2, 26 ) ) & longToint( 0xffffffff ) );
            //str += schedule[sch_index - 1].ToString() + "\n";
        }
    }


    String lic_to_base64(char[] str) {
        char[] Base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray();
        char Pad64 = '=';
        String lic_base64 = "";
        int lic_len = str.length;
        int lic_index = 0;
        char[] input = new char[3];
        char[] output = new char[4];

        while (lic_len > 2) {
            input[0] = str[lic_index++];
            input[1] = str[lic_index++];
            input[2] = str[lic_index++];
            lic_len -= 3;

            output[0] = (char) ((char) longToint( input[0] >> 2 ));
            output[1] = (char) (longToint( (input[0] & 0x03) << 4 ) + longToint( input[1] >> 4 ));
            output[2] = (char) (longToint( (input[1] & 0x0f) << 2 ) + longToint( input[2] >> 6 ));
            output[3] = (char) longToint( input[2] & 0x3f );

            lic_base64 += Base64[output[0]];
            lic_base64 += Base64[output[1]];
            lic_base64 += Base64[output[2]];
            lic_base64 += Base64[output[3]];
        }

        if (lic_len != 0) {
            input[0] = input[1] = input[2] = '\0';

            for (int i = 0; i < lic_len; i++) {
                input[i] = str[lic_index++];
            }

            output[0] = (char) longToint( input[0] >> 2 );
            output[1] = (char) (longToint( (input[0] & 0x03) << 4 ) + longToint( input[1] >> 4 ));
            output[2] = (char) (longToint( (input[1] & 0x0f) << 2 ) + longToint( input[2] >> 6 ));

            lic_base64 += Base64[output[0]];
            lic_base64 += Base64[output[1]];

            if (lic_len == 1) {
                lic_base64 += Pad64;
            } else {
                lic_base64 += Base64[output[2]];
            }

            lic_base64 += Pad64;
        }

        return lic_base64;
    }

    Logger logger = LoggerFactory.getLogger( GrantIUtils.class );

    String build_authorization_code(String str) {
        long crc = 0;
        int lic_len = str.length() + 4;
        String licence = "";

        if (lic_len >= MAX_LIC_LEN || lic_len < 35)//日期(6)+ 2 位随机 + 序列号(16)+ 事件库服务时间(3)+ 4
        {
            logger.error( "明文序列号不正确,请仔细检查输入!", "警告" );
            return "明文序列号不正确,请仔细检查输入!";
        }

        if (lic_len % 24 != 0) {
            int new_lic_len = (lic_len / 24 + 1) * 24;

            for (int i = 0; i < new_lic_len - lic_len; i++) {
                str += "0";
            }
        }

        crc = get_license_crc( str.toCharArray() );
        System.out.println( crc );
        str += String.format( "%04d", crc );

        get_scheduler();

        licence = des_ncbc_encrypt( str.toCharArray(), 1 );

        char[] chars = licence.toCharArray();
        licence = lic_to_base64( chars );

        return licence;
    }


    int serial_is_legal(String serial) {
        if (serial.trim().length() != serial_num_len) {
            return 0;
        }
            /*
            for (int i = 0; i < serial.Length; i++)
            {
                int a = int.Parse(serial[i].ToString());

                if (a > 9 || a < 0)
                {
                    return 0;
                }
            }
            */
        return 1;
    }

    public static void main(String[] args) {
        GrantIUtils g = new GrantIUtils();
        String s = g.build_authorization_code( "1806026101233314121299991120030101107020109011100111101112011" );
        System.out.println( s );
    }

    /**
     * @param port_num           waf 端口数
     * @param event_library_time 360传授权时间 月
     * @param txb_serial_num     waf 序列号
     * @return
     */
    public String waf_auth_build(int port_num, int event_library_time, String txb_serial_num) {
        String auth_code = "";
        String str = "";
        String last_str = "";
        //20171129当前时间+30天
        str += DateUtil.getYYMMDD_day( 30 ).substring( 2 );
        last_str += String.format( "%03d", event_library_time );//最多240个月
        last_str += "01011";//type module

        last_str += String.format( "%02d", LIC_MODULE_LINK_PORT_NUM );//两位
        last_str += "02" + String.format( "%02d", port_num );


        last_str += String.format( "%02d", LIC_MODULE_HTTPS ) + "011";


        last_str += String.format( "%02d", LIC_MODULE_ACCELERATE ) + "011";


        last_str += String.format( "%02d", LIC_MODULE_IPCHECK ) + "011";


        last_str += String.format( "%02d", LIC_MODULE_WEBSITE_TAKEOVER ) + "011";


        Random ran = new Random();

        str += String.format( "%02d", ran.nextInt( 100 ) );

        if (serial_is_legal( txb_serial_num.trim() ) == 0) {
            logger.error( "序列号" + txb_serial_num.trim() + "不正确,请仔细检查!", "警告" );
            return null;
        }

        str += txb_serial_num.trim();

        str += last_str;
        System.out.println( str );
        //18053070sssssssssssssssssss0040101107020009011100111101112011
        String ret = build_authorization_code( str );

        if (StringUtils.isBlank( ret )) {
            logger.error( "授权码生成失败,未知错误!", "警告" );
            return null;
        }


        return ret;
    }


    private class B21 {
        private int iv_index;
        private long c;
        private byte[] lience;

        public B21(byte[] license_key, int iv_index, long c) {
            this.iv_index = iv_index;
            this.c = longToint( c );
            this.lience = license_key;
        }

        public long getC() {
            return c;
        }

        public int getIv_index() {
            return iv_index;
        }

        public byte[] getLience() {
            return lience;
        }

        public B21 invoke() {
            c = longToint( lience[iv_index++] );
            c = longToint( c | longToint( longToint( lience[iv_index++] ) << 8 ) );
            c = longToint( c | longToint( longToint( lience[iv_index++] ) << 16 ) );
            c = longToint( c | longToint( longToint( lience[iv_index++] ) << 24 ) );
            return this;
        }
    }


    private class C21 {
        private char[] license;
        private int lic_index;
        private long b;

        public C21(char[] license, int lic_index, long b) {
            this.license = license;
            this.lic_index = lic_index;
            this.b = longToint( b );
        }

        public char[] getLicense() {
            return license;
        }

        public long getB() {
            return b;
        }

        public int getLic_index() {
            return lic_index;
        }

        public C21 invoke() {
            b = longToint( license[lic_index++] );
            b = longToint( b | longToint( longToint( license[lic_index++] ) << 8 ) );
            b = longToint( b | longToint( longToint( license[lic_index++] ) << 16 ) );
            b = longToint( b | longToint( longToint( license[lic_index++] ) << 24 ) );
            b = longToint( b );
            return this;
        }
    }

    private class PERM_OP {
        private long a;
        private long b;
        private int n;
        private long m;
        private long t;

        /* void PERM_OP(ref uint a, ref uint b, ref uint t, int n, uint m)
         {
             t = ((a >> n) ^ b) & m;
             b ^= t;
             a ^= (t << n);
         }*/
        public PERM_OP(long a, long b, long t, int n, long m) {
            this.a = longToint( a );
            this.b = longToint( b );
            this.n = n;
            this.m = longToint( m );
            this.t = longToint( t );
        }


        public long getR() {
            return a;
        }

        public long getL() {
            return b;
        }

        public long getTt() {
            return t;
        }

        public PERM_OP invoke() {
          /*  void PERM_OP(ref uint a, ref uint b, ref uint t, int n, uint m)
            {
                t = ((a >> n) ^ b) & m;
                b ^= t;
                a ^= (t << n);
            }*/
            t = longToint( a >> n );
            t = longToint( t ^ b );
            t = longToint( t & m );

//            t = longToint( (longToint( longToint( a ) >> longToint( n ) ) ^ longToint( b )) & longToint( m ) );
//            t = longToint( longToint( (longToint( longToint( a >> n ) ) ^ b) ) & m );
            b = (longToint( b ^ t ));
//            System.out.println((Long.toHexString( b ))
            a = (longToint( a ) ^ longToint( t << n ));
            return this;
        }
    }

    private class LOAD_DATA {
        private long r;
        private int s;
        private long u;
        private long t;

        public LOAD_DATA(long r, int s, long u, long t) {
            this.r = longToint( r );
            this.s = s;
            this.u = longToint( u );
            this.t = longToint( t );
        }

        public long getU() {
            return u;
        }

        public long getT() {
            return t;
        }

        public LOAD_DATA invoke() {
            u = longToint( r ^ longToint( schedule[s] ) );
            t = longToint( r ^ longToint( schedule[s + 1] ) );
            return this;
        }
    }

    private class FP {
        private long r;
        private long ll;

        public FP(long r, long ll) {
            this.r = longToint( r );
            this.ll = longToint( ll );
        }

        public long getR() {
            return r;
        }

        public long getLl() {
            return ll;
        }

        /* void FP(ref uint l, ref uint r)
         {
             uint tt = 0;
             PERM_OP(ref l, ref r, ref tt, 1, 0x55555555);
             PERM_OP(ref r, ref l, ref tt, 8, 0x00ff00ff);
             PERM_OP(ref l, ref r, ref tt, 2, 0x33333333);
             PERM_OP(ref r, ref l, ref tt, 16, 0x0000ffff);
             PERM_OP(ref l, ref r, ref tt, 4, 0x0f0f0f0f);
         }*/
        public FP invoke() {
            long ttt = 0;
//            void PERM_OP(ref uint a, ref uint b, ref uint t, int n, uint m) {
            PERM_OP invoke = new PERM_OP( longToint( ll ), longToint( r ), longToint( ttt ), 1, longToint( 0x55555555 ) ).invoke();
            r = invoke.getL();
            ll = invoke.getR();
            ttt = invoke.getTt();
            PERM_OP invoke1 = new PERM_OP( longToint( r ), longToint( ll ), longToint( ttt ), 8, longToint( 0x00ff00ff ) ).invoke();
            ll = invoke1.getL();
            r = invoke1.getR();
            ttt = invoke1.getTt();
            PERM_OP invoke2 = new PERM_OP( longToint( ll ), longToint( r ), longToint( ttt ), 2, longToint( 0x33333333 ) ).invoke();
            r = invoke2.getL();
            ll = invoke2.getR();
            ttt = invoke2.getTt();
            PERM_OP invoke3 = new PERM_OP( longToint( r ), longToint( ll ), longToint( ttt ), 16, longToint( 0x0000ffff ) ).invoke();
            ll = invoke3.getL();
            r = invoke3.getR();
            ttt = invoke3.getTt();
            PERM_OP invoke4 = new PERM_OP( longToint( ll ), longToint( r ), longToint( ttt ), 4, longToint( 0x0f0f0f0f ) ).invoke();
            r = invoke4.getL();
            ll = invoke4.getR();
            ttt = invoke4.getTt();

            r = longToint( r );
            ll = longToint( ll );
            return this;
        }
    }

    private class D_ENCRYPT {
        private long l;
        private long r;
        private long u;
        private long t;
        private int s;

        public D_ENCRYPT(long l, long r, long u, long t, int s) {
            this.l = longToint( l );
            this.r = longToint( r );
            this.u = longToint( u );
            this.t = longToint( t );
            this.s = s;
        }

        public long getL() {
            return l;
        }

        public void setL(long l) {
            this.l = l;
        }

        public long getR() {
            return r;
        }

        public void setR(long r) {
            this.r = r;
        }

        public long getU() {
            return u;
        }

        public void setU(long u) {
            this.u = u;
        }

        public long getT() {
            return t;
        }

        public void setT(long t) {
            this.t = t;
        }

        public D_ENCRYPT invoke() {
            //    void D_ENCRYPT(ref long l, ref long r, ref long u, ref long t, int s) {
            long a, b, c;
            a = b = c = 0;
            
//        LOAD_DATA( r, s, ref u, ref t );
//        void LOAD_DATA(uint a, int b, ref uint c, ref uint d) {
            LOAD_DATA LOAD_DATA = new LOAD_DATA( longToint( r ), s, longToint( u ), longToint( t ) ).invoke();
            u = LOAD_DATA.getU();
            t = LOAD_DATA.getT();
//    }
            ///
            u = longToint( u >> 2 );
            t = longToint( ROTATE( t, 6 ) );
            b = longToint( u >> 8 );
            a = longToint( u & 0x3f );
            b = longToint( b & 0x3f );
            u = longToint( u >> 16 );
            l = longToint( l ^ longToint( des_sptrans[0][(int) a] ) );
            l = longToint( l ^ longToint( des_sptrans[2][(int) b] ) );
            c = longToint( u >> 8 );
            a = longToint( u & 0x3f );
            c = longToint( c & 0x3f );

            l = longToint( l ^ longToint( des_sptrans[4][(int) a] ) );
            l = longToint( l ^ longToint( des_sptrans[6][(int) c] ) );
            b = longToint( t >> 8 );
            a = longToint( t & 0x3f );
            b = longToint( b & 0x3f );
            t = longToint( t >> 16 );

            l = longToint( l ^ longToint( des_sptrans[1][(int) a] ) );
            l = longToint( l ^ longToint( des_sptrans[3][(int) b] ) );
            c = longToint( t >> 8 );

            a = longToint( t & 0x3f );
            c = longToint( c & 0x3f );
            l = longToint( l ^ longToint( des_sptrans[5][(int) a] ) );
            l = longToint( l ^ longToint( des_sptrans[7][(int) c] ) );
            return this;
        }
    }

    private class C2ln {
        private char[] license;
        private long a;
        private long b;
        private int l;
        private int lic_index;

        public C2ln(char[] license, long a, long b, int l, int lic_index) {
            this.license = license;
            this.a = longToint( a );
            this.b = longToint( b );
            this.l = l;
            this.lic_index = lic_index;
        }

        public char[] getLicense() {
            return license;
        }

        public long getA() {
            return a;
        }

        public long getB() {
            return b;
        }

        public int getL() {
            return l;
        }

        public int getLic_index() {
            return lic_index;
        }

        public C2ln invoke() {

            int n1 = l + 8;
            int new_index = lic_index + n1;

            a = b = 0;

            while (n1 > 0) {
                switch (n1) {
                    case 8:
                        b = longToint( longToint( license[new_index--] ) << 24 );
                        break;
                    case 7:
                        b |= longToint( longToint( license[new_index--] ) << 16 );
                        break;
                    case 6:
                        b |= longToint( longToint( license[new_index--] ) << 8 );
                        break;
                    case 5:
                        b |= longToint( longToint( license[new_index--] ) );
                        break;
                    case 4:
                        a = longToint( longToint( license[new_index--] ) << 24 );
                        break;
                    case 3:
                        a |= longToint( longToint( license[new_index--] ) << 16 );
                        break;
                    case 2:
                        a |= longToint( longToint( license[new_index--] ) << 8 );
                        break;
                    case 1:
                        a |= longToint( longToint( license[new_index--] ) );
                        break;
                }

                n1--;
            }
            a = longToint( a );
            b = longToint( b );
            return this;
        }
    }

    private class HPERM_OP {
        private long m;
        private int n;
        private long c;
        private long t;


        public HPERM_OP(long c, long t, int n, long m) {
            this.c = longToint( c );
            this.t = longToint( t );
            this.n = n;
            this.m = longToint( m );
        }

        public long getM() {
            return m;
        }

        public long getN() {
            return n;
        }

        public long getC() {
            return c;
        }

        public long getT() {
            return t;
        }

        public HPERM_OP invoke() {
            t = longToint( (longToint( longToint( c ) << (16 - n) ) ^ longToint( c )) & longToint( m ) );
            c = longToint( c ^ t ^ longToint( longToint( t ) >> (16 - n) ) );
            return this;
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值