using com.fly.secute;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace Flyad7_WPF.Secute
{
    public class CreateAccessHelper
    {
        byte[] key06 = { 
            (byte)'f',0x19, (byte)'l', 0x72, (byte)'y', 0x12, (byte)'m', 0x08,
            (byte)'e',0x19, (byte)'a', 0x72, (byte)'s', 0x11, (byte)'u', 0x05,
            (byte)'r',(byte)'e', (byte)'s' };

        d3des des;
        public CreateAccessHelper()
        {
            des = new d3des();

        }

        /// <summary>
        /// 检测使用码是否正确
        /// </summary>
        /// <param name="code">序列码 byte[7]</param>
        /// <param name="access">使用码 byte[8]</param>
        /// <param name="message">消息结果</param>
        /// <returns></returns>
        public bool CheckAccess(byte[] code, byte[] access, out int hours, out string message)
        {
            hours = 0;
            byte[] bacc = access;
            string acc = byte2str(access, access.Length);
            byte[] buf1 = new byte[8];
            byte[] buf = new byte[8];
            int[] hh = new int[1];
            string ser = byte2str(code, code.Length);
            string str;
            message = "";
            byte[] keytext = new byte[12];
            byte i;

            hh[0] = -90;

            if (ser.Length != 14)
            {
                message = "序列码长度错误！！";
                return false;
            }
            else
            {
                if ((ser[12] != '0') || (ser[13] != '3') && (ser[13] != '6'))
                {
                    message = "无效序列码版本标识符！";
                    return false;
                }
                if (ser[13] != '6')
                {
                    message = "无效序列码版本标识符, 第14位必须为6 ！";
                    return false;
                }
            }
            byte[] m_serial = new byte[8];


            if (!str2byte(ser, m_serial, 6))
            {
                message = "无效序列码！";
                return false;
            }




            if (acc.Length != 16)
            {
                message = "使用码长度错误！";
                return false;
            }
            des.desDkey(key06, des.DE1);
            str2byte(acc, buf, 8);
            des.Ddes(buf, buf1);

            for (i = 0; i < 6; i++)
            {
                if (buf1[i] != m_serial[i])
                {
                    message = "无效使用码！";
                    return false;
                }
            }

            hours = byte2int(buf1[6], buf1[7]);
            message = "校验成功!";
            return true;

        }

        /// <summary>
        /// 创建授权码
        /// </summary>
        /// <param name="code">序列码 byte[7]</param>
        /// <param name="message"></param>
        /// <returns></returns>
        public bool CreateAccess(byte[] code, int hours, out byte[] access, out string message)
        {
            access = null;

            string ser = byte2str(code, code.Length);
            string str;

            if (ser.Length != 14)
            {
                message = "序列码长度错误！！";
                return false;
            }
            else
            {
                if ((ser[12] != '0') || (ser[13] != '3') && (ser[13] != '6'))
                {
                    message = "无效序列码版本标识符！";
                    return false;
                }
                if (ser[13] != '6')
                {
                    message = "无效序列码版本标识符, 第14位必须为6 ！";
                    return false;
                }
            }


            byte[] m_serial = new byte[8];
            byte[] m_secbuf = new byte[8];
            if (!str2byte(ser, m_serial, 6))
            {
                message = "无效序列码！";
                return false;
            }
            des.desDkey(key06, des.EN0);
            m_serial[7] = (byte)((hours & 0xffff) >> 8);
            m_serial[6] = (byte)(hours & 0xff);
            des.Ddes(m_serial, m_secbuf);
            access = m_secbuf.ToArray();
            message = "获取成功";
            return true;
        }

        public bool str2byte(String str, byte[] mout, int len)
        {
            byte i;

            byte[] chs = str.getBytes();
            for (i = 0; i < len; i++)
            {
                if ((chs[2 * i] >= 0x30) && (chs[2 * i] <= 0x39)) mout[i] = (byte)((chs[2 * i] - (byte)('0')) << 4);
                else if ((chs[2 * i] >= (byte)'a') && (chs[2 * i] <= (byte)'f')) mout[i] = (byte)((chs[2 * i] - (byte)'a' + 10) << 4);
                else if ((chs[2 * i] >= (byte)'A') && (chs[2 * i] <= (byte)'F')) mout[i] = (byte)((chs[2 * i] - (byte)'A' + 10) << 4);
                else return false;
                if ((chs[2 * i + 1] >= 0x30) && (chs[2 * i + 1] <= 0x39)) mout[i] |= (byte)(chs[2 * i + 1] - (byte)('0'));
                else if ((chs[2 * i + 1] >= (byte)'a') && (chs[2 * i + 1] <= (byte)'f')) mout[i] |= (byte)(chs[2 * i + 1] - (byte)'a' + 10);
                else if ((chs[2 * i + 1] >= (byte)'A') && (chs[2 * i + 1] <= (byte)'F')) mout[i] |= (byte)(chs[2 * i + 1] - (byte)'A' + 10);
                else return false;
            }
            return true;
        }
        public int byte2int(byte bl, byte bh)
        {
            int s = 0;
            if (bh < 0) s = 256 + bh;
            else s = bh;
            s = s * 256;
            if (bl < 0) s = s + 256 + bl;
            else s = s + bl;
            return s;
        }

        public string byte2str(byte[] bbuf, int len)
        {
            int i, ind;
            char[] tbl = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
            char[] buf = new char[len * 2];
            for (i = 0; i < len; i++)
            {
                ind = (byte)((bbuf[i] & 0xf0) >> 4);
                buf[2 * i] = tbl[ind];
                ind = (byte)(bbuf[i] & 0x0f);
                buf[2 * i + 1] = tbl[ind];
            }
            return new string(buf);
        }
    }

    public static class stringExt
    {
        public static byte[] getBytes(this string str)
        {
            //BytesConverter conv = new BytesConverter();
            //return (byte[])conv.ConvertBack(code, typeof(string), null, null);

            if (string.IsNullOrEmpty(str))
                return null;
            return Encoding.ASCII.GetBytes(str);// System.Text.Encoding.UTF8.GetBytes(str);
        }
        public static string toString(this byte[] arr)
        {
            return Encoding.ASCII.GetString(arr);

        }
    }
}
