不同机具的通用的第二代居民身份证读写

原文:不同机具的通用的第二代居民身份证读写

公安部已经大规模在全国范围内推广第二代居民身份证的换发工作,目前,许多地区二代证换发工作已经进行了很久。但是,相对应于二代证的推广,社会上许许多多的应用系统都还没有对二代证读卡开发相应的接口,为此,我写了一个通用的二代证机具读卡类,希望能对各位在各自的系统中开发这样的接口提供帮助。
    本类仅仅提供读卡的用法,写卡的方式我并没有写在里面,但是,相应的写调用我已经声明在里面,希望各位大侠能独自研究应用。
    该类接口具有如下特点:
    1、通用于目前市场上各个机具厂商的二代证读(写)机具。(想想,为不同厂商开发不同的接口确实令人头疼的,且由于接口不兼容,容易被客户骂死!
    2、自动适应串口、USB口的各种机具
    3、能读文字信息,但是,要想正确读照片,必须需要机具厂商的授权文件Termb.Lic,且授权文件必须放在C盘根目录下。(我总不能不照顾机具厂商的利益吧
    4、除了上面第三条之外,您甚至不用安装机具的驱动程序,接上二代证机具即可使用。
    
    废话少说,下面看实现方法:

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Reflection ;
using System.IO;


namespace ICCard
{
    public class clsICCard
    {
        //首先,声明通用接口
        [DllImport("sdtapi.dll")]
        public static extern int SDT_OpenPort(int iPortID);
        [DllImport("sdtapi.dll")]
        public static extern int SDT_ClosePort(int iPortID);
        [DllImport("sdtapi.dll")]
        public static extern int SDT_PowerManagerBegin(int iPortID, int iIfOpen);
        [DllImport("sdtapi.dll")]
        public static extern int SDT_AddSAMUser(int iPortID, string pcUserName, int iIfOpen);
        [DllImport("sdtapi.dll")]
        public static extern int SDT_SAMLogin(int iPortID, string pcUserName, string pcPasswd, int iIfOpen);
        [DllImport("sdtapi.dll")]
        public static extern int SDT_SAMLogout(int iPortID, int iIfOpen);
        [DllImport("sdtapi.dll")]
        public static extern int SDT_UserManagerOK(int iPortID, int iIfOpen);
        [DllImport("sdtapi.dll")]
        public static extern int SDT_ChangeOwnPwd(int iPortID, string pcOldPasswd, string pcNewPasswd, int iIfOpen);
        [DllImport("sdtapi.dll")]
        public static extern int SDT_ChangeOtherPwd(int iPortID, string pcUserName, string pcNewPasswd, int iIfOpen);
        [DllImport("sdtapi.dll")]
        public static extern int SDT_DeleteSAMUser(int iPortID, string pcUserName, int iIfOpen);

        [DllImport("sdtapi.dll")]
        public static extern int SDT_StartFindIDCard(int iPortID, ref int pucIIN, int iIfOpen);
        [DllImport("sdtapi.dll")]
        public static extern int SDT_SelectIDCard(int iPortID, ref int pucSN, int iIfOpen);
        [DllImport("sdtapi.dll")]
        public static extern int SDT_ReadBaseMsg(int iPortID, string pucCHMsg, ref int puiCHMsgLen, string pucPHMsg, ref int puiPHMsgLen, int iIfOpen);
        [DllImport("sdtapi.dll")]
        public static extern int SDT_ReadBaseMsgToFile(int iPortID, string fileName1, ref int puiCHMsgLen, string fileName2, ref int puiPHMsgLen, int iIfOpen);

        [DllImport("sdtapi.dll")]
        public static extern int SDT_WriteAppMsg(int iPortID, ref byte pucSendData, int uiSendLen, ref byte pucRecvData, ref int puiRecvLen, int iIfOpen);
        [DllImport("sdtapi.dll")]
        public static extern int SDT_WriteAppMsgOK(int iPortID, ref byte pucData, int uiLen, int iIfOpen);

        [DllImport("sdtapi.dll")]
        public static extern int SDT_CancelWriteAppMsg(int iPortID, int iIfOpen);
        [DllImport("sdtapi.dll")]
        public static extern int SDT_ReadNewAppMsg(int iPortID, ref byte pucAppMsg, ref int puiAppMsgLen, int iIfOpen);
        [DllImport("sdtapi.dll")]
        public static extern int SDT_ReadAllAppMsg(int iPortID, ref byte pucAppMsg, ref int puiAppMsgLen, int iIfOpen);
        [DllImport("sdtapi.dll")]
        public static extern int SDT_UsableAppMsg(int iPortID, ref byte ucByte, int iIfOpen);

        [DllImport("sdtapi.dll")]
        public static extern int SDT_GetUnlockMsg(int iPortID, ref byte strMsg, int iIfOpen);
        [DllImport("sdtapi.dll")]
        public static extern int SDT_GetSAMID(int iPortID, ref byte StrSAMID, int iIfOpen);

        [DllImport("sdtapi.dll")]
        public static extern int SDT_SetMaxRFByte(int iPortID, byte ucByte, int iIfOpen);
        [DllImport("sdtapi.dll")]
        public static extern int SDT_ResetSAM(int iPortID, int iIfOpen);

        [DllImport("WltRS.dll")]
        public static extern int GetBmp(string file_name, int intf);

        public delegate void De_ReadICCardComplete(clsEDZ objEDZ);
        public event De_ReadICCardComplete ReadICCardComplete;
        private clsEDZ objEDZ = new clsEDZ();
        private int EdziIfOpen = 1;               //自动开关串口
        int EdziPortID;        
        public clsICCard()
        {

        }
        public bool ReadICCard()
        {           
            bool bUsbPort = false;
            int intOpenPortRtn = 0;
            int rtnTemp = 0;
            int pucIIN = 0;
            int pucSN = 0;
            int puiCHMsgLen = 0;
            int puiPHMsgLen = 0;

            objEDZ = new clsEDZ();
            //检测usb口的机具连接,必须先检测usb
            for (int iPort = 1001; iPort <= 1016; iPort++)
            {
                intOpenPortRtn = SDT_OpenPort(iPort);
                if (intOpenPortRtn == 144)
                {
                    EdziPortID = iPort;
                    bUsbPort = true;
                    break;
                }
            }
            //检测串口的机具连接
            if (!bUsbPort)
            {
                for (int iPort = 1; iPort <= 2; iPort++)
                {
                    intOpenPortRtn = SDT_OpenPort(iPort);
                    if (intOpenPortRtn == 144)
                    {
                        EdziPortID = iPort;
                        bUsbPort = false;
                        break;
                    }
                }
            }
            if (intOpenPortRtn != 144)
            {                             
                MessageBox.Show("端口打开失败,请检测相应的端口或者重新连接读卡器!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }
            //在这里,如果您想下一次不用再耗费检查端口的检查的过程,您可以把 EdziPortID 保存下来,可以保存在注册表中,也可以保存在配置文件中,我就不多写了,但是,
            //您要考虑机具连接端口被用户改变的情况哦

            //下面找卡
            rtnTemp = SDT_StartFindIDCard(EdziPortID, ref pucIIN, EdziIfOpen);
            if (rtnTemp != 159)
            {
                rtnTemp = SDT_StartFindIDCard(EdziPortID, ref pucIIN, EdziIfOpen);  //再找卡
                if (rtnTemp != 159)
                {                                   
                    rtnTemp = SDT_ClosePort(EdziPortID);
                    MessageBox.Show("未放卡或者卡未放好,请重新放卡!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return false;
                }
            }
            //选卡
            rtnTemp = SDT_SelectIDCard(EdziPortID, ref pucSN, EdziIfOpen);
            if (rtnTemp != 144)
            {
                rtnTemp = SDT_SelectIDCard(EdziPortID, ref pucSN, EdziIfOpen);  //再选卡
                if (rtnTemp != 144)
                {                                      
                    rtnTemp = SDT_ClosePort(EdziPortID);
                    MessageBox.Show("读卡失败!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return false;
                }
            }
            //注意,在这里,用户必须有应用程序当前目录的读写权限
            FileInfo objFile = new FileInfo("wz.txt");
            if (objFile.Exists)
            {
                objFile.Attributes = FileAttributes.Normal;
                objFile.Delete();
            }
            objFile = new FileInfo("zp.bmp");
            if (objFile.Exists)
            {
                objFile.Attributes = FileAttributes.Normal;
                objFile.Delete();
            }
            objFile = new FileInfo("zp.wlt");
            if (objFile.Exists)
            {
                objFile.Attributes = FileAttributes.Normal;
                objFile.Delete();
            }
            rtnTemp = SDT_ReadBaseMsgToFile(EdziPortID, "wz.txt", ref puiCHMsgLen, "zp.wlt", ref puiPHMsgLen, EdziIfOpen);
            if (rtnTemp != 144)
            {                        
                rtnTemp = SDT_ClosePort(EdziPortID);
                MessageBox.Show("读卡失败!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }
            //下面解析照片,注意,如果在C盘根目录下没有机具厂商的授权文件Termb.Lic,照片解析将会失败
            if (bUsbPort)
                rtnTemp = GetBmp("zp.wlt", 2);
            else
                rtnTemp = GetBmp("zp.wlt", 1);
            switch (rtnTemp)
            {
                case 0:
                    MessageBox.Show("调用sdtapi.dll错误!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    break;
                case 1:   //正常
                    break;
                case -1:
                    MessageBox.Show("相片解码错误!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    break;
                case -2:
                    MessageBox.Show("wlt文件后缀错误!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    break;
                case -3:
                    MessageBox.Show("wlt文件打开错误!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    break;
                case -4:
                    MessageBox.Show("wlt文件格式错误!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    break;
                case -5:
                    MessageBox.Show("软件未授权!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    break;
                case -6:
                    MessageBox.Show("设备连接错误!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    break;
            }
            rtnTemp = SDT_ClosePort(EdziPortID);
            FileInfo f = new FileInfo("wz.txt");
            FileStream fs = f.OpenRead();
            byte[] bt = new byte[fs.Length];
            fs.Read(bt, 0, (int)fs.Length);
            fs.Close();

            string str = System.Text.UnicodeEncoding.Unicode.GetString(bt);

            objEDZ.Name = System.Text.UnicodeEncoding.Unicode.GetString(bt, 0, 30).Trim();
            objEDZ.Sex_Code = System.Text.UnicodeEncoding.Unicode.GetString(bt, 30, 2).Trim();
            objEDZ.NATION_Code = System.Text.UnicodeEncoding.Unicode.GetString(bt, 32, 4).Trim();
            string strBird = System.Text.UnicodeEncoding.Unicode.GetString(bt, 36, 16).Trim();
            objEDZ.BIRTH = Convert.ToDateTime(strBird.Substring(0, 4) + "年" + strBird.Substring(4, 2) + "月" + strBird.Substring(6) + "日");
            objEDZ.ADDRESS = System.Text.UnicodeEncoding.Unicode.GetString(bt, 52, 70).Trim();
            objEDZ.IDC = System.Text.UnicodeEncoding.Unicode.GetString(bt, 122, 36).Trim();
            objEDZ.REGORG = System.Text.UnicodeEncoding.Unicode.GetString(bt, 158, 30).Trim();
            string strTem = System.Text.UnicodeEncoding.Unicode.GetString(bt, 188, bt.GetLength(0) - 188).Trim();
            objEDZ.STARTDATE = Convert.ToDateTime(strTem.Substring(0, 4) + "年" + strTem.Substring(4, 2) + "月" + strTem.Substring(6, 2) + "日");
            strTem = strTem.Substring(8);
            if (strTem.Trim() != "长期")
            {
                objEDZ.ENDDATE = Convert.ToDateTime(strTem.Substring(0, 4) + "年" + strTem.Substring(4, 2) + "月" + strTem.Substring(6, 2) + "日");
            }
            else
            {
                objEDZ.ENDDATE = DateTime.MaxValue;
            }
            objFile = new FileInfo("zp.bmp");
            if (objFile.Exists)
            {
                Image img = Image.FromFile("zp.bmp");
                objEDZ.PIC_Image=(Image)img.Clone();
                System.IO.MemoryStream m = new MemoryStream();
                img.Save(m, System.Drawing.Imaging.ImageFormat.Jpeg);
                objEDZ.PIC_Byte = m.ToArray();
                img.Dispose();
                img = null;
            }
            ReadICCardComplete(objEDZ);           
            return true;
        }


    }
    public class clsEDZ
    {
        private System.Collections.SortedList lstMZ = new SortedList();
        private string _Name;   //姓名
        private string _Sex_Code;   //性别代码
        private string _Sex_CName;   //性别
        private string _IDC;      //身份证号码
        private string _NATION_Code;   //民族代码
        private string _NATION_CName;   //民族
        private DateTime _BIRTH;     //出生日期
        private string _ADDRESS;    //住址
        private string _REGORG;     //签发机关
        private DateTime _STARTDATE;    //身份证有效起始日期
        private DateTime _ENDDATE;    //身份证有效截至日期
        private string _Period_Of_Validity_Code;   //有效期限代码,许多原来系统上面为了一代证考虑,常常存在这样的字段,二代证中已经没有了
        private string _Period_Of_Validity_CName;   //有效期限
        private byte[] _PIC_Byte;    //照片二进制
        private Image _PIC_Image;   //照片

        public clsEDZ()
        {
            lstMZ.Add("01", "汉族");
            lstMZ.Add("02", "蒙古族");
            lstMZ.Add("03", "回族");
            lstMZ.Add("04", "藏族");
            lstMZ.Add("05", "维吾尔族");
            lstMZ.Add("06", "苗族");
            lstMZ.Add("07", "彝族");
            lstMZ.Add("08", "壮族");
            lstMZ.Add("09", "布依族");
            lstMZ.Add("10", "朝鲜族");
            lstMZ.Add("11", "满族");
            lstMZ.Add("12", "侗族");
            lstMZ.Add("13", "瑶族");
            lstMZ.Add("14", "白族");
            lstMZ.Add("15", "土家族");
            lstMZ.Add("16", "哈尼族");
            lstMZ.Add("17", "哈萨克族");
            lstMZ.Add("18", "傣族");
            lstMZ.Add("19", "黎族");
            lstMZ.Add("20", "傈僳族");
            lstMZ.Add("21", "佤族");
            lstMZ.Add("22", "畲族");
            lstMZ.Add("23", "高山族");
            lstMZ.Add("24", "拉祜族");
            lstMZ.Add("25", "水族");
            lstMZ.Add("26", "东乡族");
            lstMZ.Add("27", "纳西族");
            lstMZ.Add("28", "景颇族");
            lstMZ.Add("29", "柯尔克孜族");
            lstMZ.Add("30", "土族");
            lstMZ.Add("31", "达翰尔族");
            lstMZ.Add("32", "仫佬族");
            lstMZ.Add("33", "羌族");
            lstMZ.Add("34", "布朗族");
            lstMZ.Add("35", "撒拉族");
            lstMZ.Add("36", "毛南族");
            lstMZ.Add("37", "仡佬族");
            lstMZ.Add("38", "锡伯族");
            lstMZ.Add("39", "阿昌族");
            lstMZ.Add("40", "普米族");
            lstMZ.Add("41", "塔吉克族");
            lstMZ.Add("42", "怒族");
            lstMZ.Add("43", "乌孜别克族");
            lstMZ.Add("44", "俄罗斯族");
            lstMZ.Add("45", "鄂温克族");
            lstMZ.Add("46", "德昂族");
            lstMZ.Add("47", "保安族");
            lstMZ.Add("48", "裕固族");
            lstMZ.Add("49", "京族");
            lstMZ.Add("50", "塔塔尔族");
            lstMZ.Add("51", "独龙族");
            lstMZ.Add("52", "鄂伦春族");
            lstMZ.Add("53", "赫哲族");
            lstMZ.Add("54", "门巴族");
            lstMZ.Add("55", "珞巴族");
            lstMZ.Add("56", "基诺族");
            lstMZ.Add("57", "其它");
            lstMZ.Add("98", "外国人入籍");
        }

        public string Name
        {
            get { return _Name; }
            set { _Name = value; }
        }
        public string Sex_Code
        {
            get { return _Sex_Code; }
            set
            {
                _Sex_Code = value;
                switch (value)
                {
                    case "1":
                        Sex_CName = "男";
                        break;
                    case "2":
                        Sex_CName = "女";
                        break;
                }
            }
        }
        public string Sex_CName
        {
            get { return _Sex_CName; }
            set { _Sex_CName = value; }
        }
        public string IDC
        {
            get { return _IDC; }
            set { _IDC = value; }
        }
        public string NATION_Code
        {
            get { return _NATION_Code; }
            set
            {
                _NATION_Code = value;
                if (lstMZ.Contains(value))
                    NATION_CName = lstMZ[value].ToString();
            }
        }
        public string NATION_CName
        {
            get { return _NATION_CName; }
            set { _NATION_CName = value; }
        }
        public DateTime BIRTH
        {
            get { return _BIRTH; }
            set { _BIRTH = value; }
        }
        public string ADDRESS
        {
            get { return _ADDRESS; }
            set { _ADDRESS = value; }
        }
        public string REGORG
        {
            get { return _REGORG; }
            set { _REGORG = value; }
        }
        public DateTime STARTDATE
        {
            get { return _STARTDATE; }
            set { _STARTDATE = value; }
        }
        public DateTime ENDDATE
        {
            get { return _ENDDATE; }
            set
            {
                _ENDDATE = value;
                if (_ENDDATE == DateTime.MaxValue)
                {
                    _Period_Of_Validity_Code = "3";
                    _Period_Of_Validity_CName = "长期";
                }
                else
                {
                    if (_STARTDATE != DateTime.MinValue)
                    {
                        switch (value.AddDays(1).Year - _STARTDATE.Year)
                        {
                            case 5:
                                _Period_Of_Validity_Code = "4";
                                _Period_Of_Validity_CName = "5年";
                                break;
                            case 10:
                                _Period_Of_Validity_Code = "1";
                                _Period_Of_Validity_CName = "10年";
                                break;
                            case 20:
                                _Period_Of_Validity_Code = "2";
                                _Period_Of_Validity_CName = "20年";
                                break;
                        }
                    }
                }

            }
        }
        public string Period_Of_Validity_Code
        {
            get { return _Period_Of_Validity_Code; }
            set { _Period_Of_Validity_Code = value; }
        }
        public string Period_Of_Validity_CName
        {
            get { return _Period_Of_Validity_CName; }
            set { _Period_Of_Validity_CName = value; }
        }
        public byte[] PIC_Byte
        {
            get { return _PIC_Byte; }
            set { _PIC_Byte = value; }
        }
        public Image PIC_Image
        {
            get { return _PIC_Image; }
            set { _PIC_Image = value; }
        }



    }
}

类中使用到了两个dll文件(sdtapi.dll和WltRS.dll),点击这里下载!

时间: 2024-10-11 22:25:51

不同机具的通用的第二代居民身份证读写的相关文章

GPRS GPRS(General Packet Radio Service)是通用分组无线服务技术的简称,它是GSM移动电话用户可用的一种移动数据业务,属于第二代移动通信中的数据传输技术

GPRS 锁定 本词条由“科普中国”百科科学词条编写与应用工作项目 审核 . GPRS(General Packet Radio Service)是通用分组无线服务技术的简称,它是GSM移动电话用户可用的一种移动数据业务,属于第二代移动通信中的数据传输技术.GPRS可说是GSM的延续.GPRS和以往连续在频道传输的方式不同,是以封包(Packet)式来传输,因此使用者所负担的费用是以其传输资料单位计算,并非使用其整个频道,理论上较为便宜.GPRS的传输速率可提升至56甚至114Kbps.[1]

【深度解析】Google第二代深度学习引擎TensorFlow开源

作者:王嘉俊 王婉婷 TensorFlow 是 Google 第二代深度学习系统,今天宣布完全开源.TensorFlow 是一种编写机器学习算法的界面,也可以编译执行机器学习算法的代码.使用 TensorFlow 编写的运算可以几乎不用更改,就能被运行在多种异质系统上,从移动设备(例如手机和平板)到拥有几百台的机器和几千个 GPU 之类运算设备的大规模分布式系统. TensorFlow 降低了深度学习的使用门槛,让从业人员能够更简单和方便地开发新产品.作为Google 发布的“平台级产品”,很多

TensorFlow【机器学习】:如何正确的掌握Google深度学习框架TensorFlow(第二代分布式机器学习系统)?

本文标签:   机器学习 TensorFlow Google深度学习框架 分布式机器学习 唐源 VGG REST   服务器 自 2015 年底开源到如今更快.更灵活.更方便的 1.0 版本正式发布,由 Google 推出的第二代分布式机器学习系统 TensorFlow一直在为我们带来惊喜,一方面是技术层面持续的迭代演进,从分布式版本.服务框架 TensorFlow Serving.上层封装 TF.Learn 到 Windows 支持.JIT 编译器 XLA.动态计算图框架 Fold 等,以及

软件测试不再黑盒— threadingtest带来第二代白盒覆盖率技术

软件测试不再黑盒- threadingtest带来第二代白盒覆盖率技术 穿线测试对于测试界的一个重大创新在于,在白盒测试理论出现数十年以后,上海零一拼装信息技术有限公司结合在测试理论方面十余年的潜心研究,率先提出了第二代覆盖率技术,这绝对不是一个口号,而是ZOA真正对于白盒测试的理解以及对于标准第三方测试服务的深度理解经过数年的基础研究以及2年有余的研发而推出的达到商用标准的技术.现在先让我们温习下经典的测试理论: 1.测试方法论 黑盒功能测试法 黑盒功能测试法, 是把要测试的软件看成一个 "黑

谷歌开源第二代机器学习系统 TensorFlow

深度学习对计算机科学而言,是有相当深远的影响的.它让尖端科技研究.开发数千万人日常使用的产品成为可能.Research宣布推出第二代机器学习系统TensorFlow,针对先前的DistBelief的短板有了各方面的加强,更重要的是,它是开源的,任何人都可以用. 谷歌内部深度学习结构DistBelief开发于2011年,它让谷歌能够针对数据中心的数千核心,构建更为大型的神经网络和规模训练,典型的应用像是提升谷歌应用中的语音识别能力,以及为谷歌搜索加入图片搜索功能. 不过DistBelief存在一些

第二代支付系统及电票线上清算相关知识

二代支付系统 国家处理中心(NPC):NPC是人民银行连接支付系统所有城市节点和特许参与者的中枢节点,负责接收.转发各CCPC和接收.处理特许参与者的支付指令,以及资金清算的一组硬件和软件系统的总称.参加支付系统的直接参与者必须在人民银行国家处理中心开设清算账户. 城市处理中心(CCPC):CCPC是人民银行支付系统的城市节点,连接NPC和各直接参与者,负责在NPC和直接参与者之间接收和转发支付指令的一组硬件和软件系统的总称. 人民银行二代支付系统  CNAPS(China National A

hyperv 创建第二代虚拟机

环境:宿主机windows 8.1,虚拟机:windows 8.1 硬件:笔记本电脑,无线网络,没有有线网络网络配置先不设置 1.安装hyperv,控制面版-->程序和功能-->启用或关闭windows功能-->Hyper-v下的内容全选,安装就可以了. 2.创建虚拟机,如下图 第二代只支持windows 8 或windows server 2012及以后新版本的系统 网络这里先不做配置 完成之后,对虚拟机进行设置 确定完成后,开始启动虚拟机,连接-->启动 这里出错,图没有截到,

第二代微服务网关组件 - Spring Cloud Gateway

[TOC] 初识Spring Cloud Gateway 简介: Spring Cloud Gateway是Spring Cloud体系的第二代网关组件,基于Spring 5.0的新特性WebFlux进行开发,底层网络通信框架使用的是Netty,所以其吞吐量高.性能强劲,未来将会取代第一代的网关组件Zuul.Spring Cloud Gateway可以通过服务发现组件自动转发请求,默认集成了Ribbon做负载均衡,以及默认使用Hystrix对网关进行保护,当然也可以选择其他的容错组件,例如Sen

实现“第二代互联网”愿景的重要途径--区块链技术

YottaChain是一个完全靠价值就能支撑币价的项目.YottaChain用区块链改造数据存储行业,利用独家核心技术和强大的专业能力做到比现有的中心化存储的可靠性提高一万倍以上,还有非常奢侈的容灾特性和抗DDoS能力,成本却只有中心化存储的几分之一,现有存储用户每年可能会花费多达数百亿美元的资金购买YTA(YottaChain的流通币),目的是用YTA购买所需要的高品质低价格的存储能力. 数据存储有一个非常重要的特性,称为数据去重.如果多个人拥有相同的数据,不重复存储而是合并共用同一份空间,称