精华内容
下载资源
问答
  • 遗传算法和BP人工神经网络算法C++实现代码

    千次下载 热门讨论 2014-09-22 15:18:01
    遗传算法和BP人工神经网络算法C++实现代码是通过c++来 完成两个算法,里面有详细的注释说明,希望对你有用
  • 国密SM9算法C++实现之一:算法简介

    千次阅读 2018-08-17 14:04:08
    SM9算法C++实现系列目录: 国密SM9算法C++实现之一:算法简介 国密SM9算法C++实现之二:测试工具 国密SM9算法C++实现之三:椭圆曲线接口、参数初始化 国密SM9算法C++实现之四:基本功能函数与KGC...

    SM9算法C++实现系列目录:

    国密SM9算法C++实现之一:算法简介

     

     


    SM9标识密码算法是由国密局发布的一种IBE(Identity-Based Encryption)算法。IBE算法以用户的身份标识作为公钥,不依赖于数字证书。国密SM9算法标准包括5个文档,分别为: 
    《GMT 0044-2016 SM9标识密码算法:第1部分 总则》 
    《GMT 0044-2016 SM9标识密码算法:第2部分 数字签名算法》 
    《GMT 0044-2016 SM9标识密码算法:第3部分 密钥交换协议》 
    《GMT 0044-2016 SM9标识密码算法:第4部分 密钥封装机制和公钥加密算法》 
    《GMT 0044-2016 SM9标识密码算法:第5部分 参数定义》

    曲线参数

    SM9是基于256位的BN椭圆曲线的,使用素域 FpFp 和有限域 Fp2Fp2,双线性对使用R-ate。曲线参数主要包括:

    • 椭圆曲线方程:y2=x3+by2=x3+b
    • 方程参数b:05
    • 参数t: 
      60000000 0058F98A
    • 基域特征q: 
      B6400000 02A3A6F1 D603AB4F F58EC745 21F2934B 1A7AEEDB E56F9B27 E351457D
    • 群的阶N 
      B6400000 02A3A6F1 D603AB4F F58EC744 49F2934B 18EA8BEE E56EE19C D69ECF25
    • 余因子cf:1
    • 群1 的生成元P1 = (xp1 , yp1): 
      坐标xp1: 
      93DE051D 62BF718F F5ED0704 487D01D6 E1E40869 09DC3280 E8C4E481 7C66DDDD 
      坐标yp1: 
      21FE8DDA 4F21E607 63106512 5C395BBC 1C1C00CB FA602435 0C464CD7 0A3EA616
    • 群2 的生成元P2 = (xp2, yp2): 
      坐标xp2: 
      (85AEF3D0 78640C98 597B6027 B441A01F F1DD2C19 0F5E93C4 54806C11 D8806141 , 
      37227552 92130B08 D2AAB97F D34EC120 EE265948 D19C17AB F9B7213B AF82D65B ) 
      坐标yp2: 
      (17509B09 2E845C12 66BA0D26 2CBEE6ED 0736A96F A347C8BD 856DC76B 84EBEB96 , 
      A7CF28D5 19BE3DA6 5F317015 3D278FF2 47EFBA98 A71A0811 6215BBA5 C999A7C7 )

    详细参数可参考国密局SM9文档。

    SM9算法主要包括密钥部分部分和算法部分。

    • 密钥部分:包括主密钥对(公钥和私钥)和用户私钥
    • 算法部分:包括签名验签算法、密钥封装解封算法、加密解密算法和密钥交换算法

    密钥部分

    SM9算法的密钥由KGC(密钥生成中心)产生,主要包括KGC的主密钥对和用户的私钥。 
    主密钥对分为签名主密钥对加密主密钥对

    • 签名主密钥对:其私钥是一个在[1,N-1]范围内的随机数;公钥是G2群的基点P2的倍点,倍数为私钥。
    • 加密主密钥对:其私钥是一个在[1,N-1]范围内的随机数;公钥是G1群的基点P1的倍点,倍数为私钥。

    主密钥对的公私钥用在不同场景,其中主私钥仅用于计算用户私钥;主公钥则由KGC公开并用在其他部分。同时,签名主公钥仅用于签名和验签算法;加密主公钥则用于密钥封装、加密和密钥交换中。

    用户私钥由KGC产生,包括签名私钥和加密私钥。

    • 签名私钥:是G1群的基点P1的倍点。签名私钥仅用于签名中
    • 加密私钥:是G2群的基点P2的倍点。加密私钥用于密钥解封、解密和密钥交换中私钥

    KGC使用主私钥和用户身份标识(以下简称ID)生成用户的私钥。

    算法部分

    SM9算法包括签名验签、密钥封装解封、加密解密和密钥交换四大部分。

    • 签名算法:使用签名主公钥和签名者的签名私钥给数据签名
    • 验签算法:使用签名主公钥和签名者ID验证签名
    • 密钥封装算法:使用加密主公钥和密钥解封者(使用对称密钥的另一方)ID封装一个对称密钥
    • 密钥解封算法:使用加密主公钥和密钥解封者ID解出封装了的对称密钥
    • 加密算法:使用加密主公钥和解密者ID加密数据
    • 解密算法:使用解密者的加密私钥和解密者ID解密数据
    • 密钥交换算法:密钥交换双方使用加密主公钥、自己的加密私钥和双方的ID协商出一个共享密钥

    用户身份标识符:ID

    总结上述描述,可见在SM9算法中的用户身份标识ID主要用于用于私钥生成、验签、密钥封装解封、加密解密封和密钥交换。各部分的ID描述如下:

    • 私钥生成:ID是私钥属主的ID
    • 验签:ID是签名者的ID
    • 密钥封装解封:ID是解封者的ID
    • 加密解密:ID是解密者的ID
    • 密钥交换:发起方和响应方都需要自己的ID和对方的ID

    SM9算法的简介就介绍到这里,具体的算法描述和数学理论课参考SM9算法标准,以及后续文章。

    展开全文
  • GA遗传算法C++实现,控制台演示

    千次下载 热门讨论 2011-11-05 18:25:29
    遗传算法 C++实现 控制台演示版本 附有详尽注释 注:因为是单数浮点数编码,所以未使用基因重组函数 如果看完仍然不懂,欢迎参看本人博客的一篇关于GA的文章 ...
  • SHA256算法C++实现

    千次阅读 2019-11-14 14:03:16
    一、SHA256算法介绍与原理详解 ...二、SHA256算法C++实现 /* * Filename: sha256.hpp * Author: YF * Brief: SHA256算法实现 * Version: V1.0.0 * Update log: * 1)20191108-20191113 V1.0.0 * ...

    一、SHA256算法介绍与原理详解
    见博客《SHA256算法原理详解

    二、SHA256算法C++实现
    1)sha256.hpp

    /*
    * Filename: sha256.hpp
    * Author: L.Y.
    * Brief: SHA256算法实现
    * Version: V1.0.0
    * Update log: 
    *     1)20191108-20191113 V1.0.0
    *         1、初次版本。
    * TODO: 
    * Attention: 
    *     1)输入信息中有中文时,得到的数字指纹与使用SHA256在线加密工具得到数字指纹可能不相同。
    *        原因是中文的编码方式不同。
    */
    
    #ifndef SHA256_HPP
    #define SHA256_HPP
    
    #include <stdint.h>
    
    #include <string>
    #include <vector>
    
    namespace ly {
    
    //
    // \brief: SHA256算法实现
    //
    class Sha256
    {
    public:
        //! 默认构造函数
        Sha256() {}
    
        //! 析构函数
        virtual ~Sha256() {}
    
        /** @brief: 使用SHA256算法,获取输入信息的摘要(数字指纹)
        @param[in] message: 输入信息
        @param[out] _digest: 摘要(数字指纹)
        @return: 是否成功
        */
        bool encrypt(const std::vector<uint8_t>& message, 
                     std::vector<uint8_t>* _digest);
    
        /** @brief: 获取十六进制表示的信息摘要(数字指纹)
        @param[in] message: 输入信息
        @return: 十六进制表示的信息摘要(数字指纹)
        */
        std::string getHexMessageDigest(const std::string& message);
    
    protected:
        /// SHA256算法中定义的6种逻辑运算 ///
        inline uint32_t ch(uint32_t x, uint32_t y, uint32_t z) const;
        inline uint32_t maj(uint32_t x, uint32_t y, uint32_t z) const;
        inline uint32_t big_sigma0(uint32_t x) const;
        inline uint32_t big_sigma1(uint32_t x) const;
        inline uint32_t small_sigma0(uint32_t x) const;
        inline uint32_t small_sigma1(uint32_t x) const;
    
        /** @brief: SHA256算法对输入信息的预处理,包括“附加填充比特”和“附加长度值”
        附加填充比特: 在报文末尾进行填充,先补第一个比特为1,然后都补0,直到长度满足对512取模后余数是448。需要注意的是,信息必须进行填充。
        附加长度值: 用一个64位的数据来表示原始消息(填充前的消息)的长度,并将其补到已经进行了填充操作的消息后面。
        @param[in][out] _message: 待处理的信息
        @return: 是否成功
        */
        bool preprocessing(std::vector<uint8_t>* _message) const;
    
        /** @brief: 将信息分解成连续的64Byte大小的数据块
        @param[in] message: 输入信息,长度为64Byte的倍数
        @param[out] _chunks: 输出数据块
        @return: 是否成功
        */
        bool breakTextInto64ByteChunks(const std::vector<uint8_t>& message, 
                                       std::vector<std::vector<uint8_t>>* _chunks) const;
    
        /** @brief: 由64Byte大小的数据块,构造出64个4Byte大小的字。
        构造算法:前16个字直接由数据块分解得到,其余的字由如下迭代公式得到:
                W[t] = small_sigma1(W[t-2]) + W[t-7] + small_sigma0(W[t-15]) + W[t-16]
        @param[in] chunk: 输入数据块,大小为64Byte
        @param[out] _words: 输出字
        @return: 是否成功
        */
        bool structureWords(const std::vector<uint8_t>& chunk, 
                            std::vector<uint32_t>* _words) const;
    
        /** @breif: 基于64个4Byte大小的字,进行64次循环加密
        @param[in] words: 64个4Byte大小的字
        @param[in][out] _message_digest: 信息摘要
        @return: 是否成功
        */
        bool transform(const std::vector<uint32_t>& words, 
                       std::vector<uint32_t>* _message_digest) const;
    
        /** @brief: 输出最终的哈希值(数字指纹)
        @param[in] input: 步长为32bit的哈希值
        @param[out] _output: 步长为8bit的哈希值
        @return: 是否成功
        */
        bool produceFinalHashValue(const std::vector<uint32_t>& input,
                                   std::vector<uint8_t>* _output) const;
    
    
    private:
        static std::vector<uint32_t> initial_message_digest_; // 在SHA256算法中的初始信息摘要,这些常量是对自然数中前8个质数的平方根的小数部分取前32bit而来。
        static std::vector<uint32_t> add_constant_; // 在SHA256算法中,用到64个常量,这些常量是对自然数中前64个质数的立方根的小数部分取前32bit而来。
    };
    
    // 内联函数&模版函数的定义 /
    
    inline uint32_t Sha256::ch(uint32_t x, uint32_t y, uint32_t z) const
    {
        return (x & y) ^ ((~x) & z);
    }
    
    inline uint32_t Sha256::maj(uint32_t x, uint32_t y, uint32_t z) const
    {
        return (x & y) ^ (x & z) ^ (y & z);
    }
    
    inline uint32_t Sha256::big_sigma0(uint32_t x) const
    {
        return (x >> 2 | x << 30) ^ (x >> 13 | x << 19) ^ (x >> 22 | x << 10);
    }
    
    inline uint32_t Sha256::big_sigma1(uint32_t x) const
    {
        return (x >> 6 | x << 26) ^ (x >> 11 | x << 21) ^ (x >> 25 | x << 7);
    }
    
    inline uint32_t Sha256::small_sigma0(uint32_t x) const
    {
        return (x >> 7 | x << 25) ^ (x >> 18 | x << 14) ^ (x >> 3);
    }
    
    inline uint32_t Sha256::small_sigma1(uint32_t x) const
    {
        return (x >> 17 | x << 15) ^ (x >> 19 | x << 13) ^ (x >> 10);
    }
    
    } // namespace ly
    
    #endif // SHA256_HPP
    

    2)sha256.cpp

    /*
    * Filename: sha256.cpp
    * Author: L.Y.
    * Brief: SHA256算法实现
    * Version: V1.0.0
    * Update log:
    *     1)20191108-20191113 V1.0.0
    *         1、初次版本。
    * TODO:
    * Attention:
    *     1)输入信息中有中文时,得到的数字指纹与使用SHA256在线加密工具得到数字指纹可能不相同。
    *        原因是中文的编码方式不同。
    */
    
    #include "sha256.hpp"
    
    #include <iomanip>
    #include <sstream>
    #include <string>
    #include <vector>
    
    namespace ly {
    
    std::vector<uint32_t> Sha256::initial_message_digest_ = 
    { 
        0x6a09e667, 0xbb67ae85, 0x3c6ef372,
        0xa54ff53a, 0x510e527f, 0x9b05688c,
        0x1f83d9ab, 0x5be0cd19 
    };
    
    std::vector<uint32_t> Sha256::add_constant_ = 
    {
        0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,
        0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,
        0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,
        0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,
        0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,
        0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,
        0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,
        0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
    };
    
    bool Sha256::encrypt(const std::vector<uint8_t>& input_message, 
                         std::vector<uint8_t>* _digest)
    {
        if (!input_message.empty() && _digest)
        {
            //! 文本预处理
            std::vector<uint8_t> message = input_message;
            preprocessing(&message);
    
            //! 将文本分解成连续的64Byte大小的数据块
            std::vector<std::vector<uint8_t>> chunks;
            breakTextInto64ByteChunks(message, &chunks);
    
            //! 由64Byte大小的数据块,构造出64个4Byte大小的字。然后进行循环迭代。
            std::vector<uint32_t> message_digest(initial_message_digest_); // 初始化信息摘要
    
            std::vector<uint32_t> words;
            for (const auto& chunk : chunks)
            {
                structureWords(chunk, &words);
                transform(words, &message_digest);
            }
    
            //! 获取最终结果
            produceFinalHashValue(message_digest, _digest);
    
            return true;
        }
        else
        {
            return false;
        }
    }
    
    std::string Sha256::getHexMessageDigest(const std::string& message)
    {
        if (!message.empty())
        {
            std::vector<uint8_t> __message;
            for (auto it = message.begin(); it != message.end(); ++it)
            {
                __message.push_back(static_cast<uint8_t>(*it));
            }
    
            std::vector<uint8_t> digest;
            encrypt(__message, &digest);
    
            std::ostringstream o_s;
            o_s << std::hex << std::setiosflags(std::ios::uppercase);
            for (auto it = digest.begin(); it != digest.end(); ++it)
            {
                o_s << std::setw(2) << std::setfill('0')
                    << static_cast<unsigned short>(*it);
            }
    
            return o_s.str();
        }
        else
        {
            return "";
        }
    }
    
    bool Sha256::preprocessing(std::vector<uint8_t>* _message) const
    {
        if (_message)
        {
            const uint64_t original_bit_size = _message->size() * 8;
    
            //! 附加填充比特
            size_t remainder = _message->size() % 64;
            if (remainder < 56)
            {
                _message->push_back(0x80); // ox80 == 10000000
                for (size_t i = 1; i < 56 - remainder; ++i)
                {
                    _message->push_back(0x00);
                }
            }
            else if (remainder == 56)
            {
                _message->push_back(0x80);
                for (size_t i = 1; i < 64; ++i)
                {
                    _message->push_back(0x00);
                }
            }
            else
            {
                _message->push_back(0x80);
                for (size_t i = 1; i < 64 - remainder + 56; ++i)
                {
                    _message->push_back(0x00);
                }
            }
    
            //! 附加原始文本的长度值
            for (int i = 1; i <= 8; ++i)
            {
                uint8_t c = static_cast<uint8_t>(original_bit_size >> (64 - 8 * i));
                _message->push_back(c);
            }
    
            return true;
        }
        else
        {
            return false;
        }
    }
    
    bool Sha256::breakTextInto64ByteChunks(const std::vector<uint8_t>& message, 
                                           std::vector<std::vector<uint8_t>>* _chunks) const
    {
        if (_chunks && 0 == message.size() % 64)
        {
            _chunks->clear(); // 清空输出buffer
    
            size_t quotient = message.size() / 64;
            for (size_t i = 0; i < quotient; ++i)
            {
                std::vector<uint8_t> temp(message.begin() + i * 64, message.begin() + (i + 1) * 64);
                _chunks->push_back(temp);
            }
            return true;
        }
        else
        {
            return false;
        }
    }
    
    bool Sha256::structureWords(const std::vector<uint8_t>& chunk, 
                                std::vector<uint32_t>* _words) const
    {
        if (_words && 64 == chunk.size())
        {
            _words->resize(64);
    
            auto& words = *_words;
            for (int i = 0; i < 16; ++i)
            {
                words[i] = (static_cast<uint32_t>(chunk[i * 4]) << 24)
                           | (static_cast<uint32_t>(chunk[i * 4 + 1]) << 16)
                           | (static_cast<uint32_t>(chunk[i * 4 + 2]) << 8)
                           | static_cast<uint32_t>(chunk[i * 4 + 3]);
            }
            for (int i = 16; i < 64; ++i)
            {
                words[i] = small_sigma1(words[i - 2])
                           + words[i - 7]
                           + small_sigma0(words[i - 15])
                           + words[i - 16];
            }
            return true;
        }
        else
        {
            return false;
        }
    }
    
    bool Sha256::transform(const std::vector<uint32_t>& words, 
                           std::vector<uint32_t>* _message_digest) const
    {
        if (_message_digest && 8 == _message_digest->size() && 64 == words.size())
        {
            std::vector<uint32_t> d = *_message_digest;
    
            for (int i = 0; i < 64; ++i)
            {
                uint32_t temp1 = d[7] + big_sigma1(d[4]) + ch(d[4], d[5], d[6]) + add_constant_[i] + words[i];
                uint32_t temp2 = big_sigma0(d[0]) + maj(d[0], d[1], d[2]);
                
                d[7] = d[6];
                d[6] = d[5];
                d[5] = d[4];
                d[4] = d[3] + temp1;
                d[3] = d[2];
                d[2] = d[1];
                d[1] = d[0];
                d[0] = temp1 + temp2;
            }
    
            for (int i = 0; i < 8; ++i)
            {
                (*_message_digest)[i] += d[i];
            }
    
            return true;
        }
        else
        {
            return false;
        }
    }
    
    bool Sha256::produceFinalHashValue(const std::vector<uint32_t>& input, 
                                       std::vector<uint8_t>* _output) const
    {
        if (_output)
        {
            _output->clear();
    
            for (auto it = input.begin(); it != input.end(); ++it)
            {
                for (int i = 0; i < 4; i++)
                {
                    _output->push_back(static_cast<uint8_t>((*it) >> (24 - 8 * i)));
                }
            }
            return true;
        }
        else
        {
            return false;
        }
    }
    
    } // namespace ly
    

    3)main.cpp

    /*
    * Filename: main.cpp
    * Author: L.Y.
    * Brief: SHA256算法测试
    */
    
    #include <iostream>
    #include <string>
    
    #include "sha256.hpp"
    
    int main()
    {
        std::string message = "seek truth from facts"; // 待加密的信息
    
        ly::Sha256 sha256; // 初始化Sha256对象
        std::string message_digest = sha256.getHexMessageDigest(message); // 加密
    
        std::cout << message_digest << std::endl; // 输出加密结果
        getchar();
        
    	return 0;
    }
    
    展开全文
  • 国密SM9算法C++实现之四:签名验签算法 国密SM9算法C++实现之四:签名验签算法 签名算法流程 签名值 Signature.h 签名算法实现 验签算法流程 验签算法实现 实现完KGC...

    SM9算法C++实现系列目录:

    国密SM9算法C++实现之五:签名验签算法

    实现完KGC部分后,可以开始实现SM9算法部分。本篇描述签名验签算法的实现。

    签名算法流程

    SM9标准文档中描述的签名算法流程如下所示:

    这里写图片描述

    其流程图为:
    这里写图片描述

    根据算法描述,定义接口函数:

    	/** 
    	* 签名
    	* 
    	* @param masterPublicKey 签名主公钥
    	* @param prikey 用户签名私钥
    	* @param data 待签数据
    	* @return 签名值
    	* @throw std::exception SM9_ERROR_NOT_INIT | SM9_ERROR_CALC_RATE
    	*/
    	static Signature sign(const string& masterPublicKey, const string& prikey, const string& data);
    

    签名值

    SM9签名结果包括h和S两个部分,对此,也简单将其封装为一个类。

    Signature.h

    
    #ifndef YY_SM9_SIGNATURE_INCLUDE_H__
    #define YY_SM9_SIGNATURE_INCLUDE_H__
    
    #pragma once
    
    #include <string>
    
    using namespace std;
    
    /**
    * 签名值.
    * @author YaoYuan
    */
    class Signature {
    public:
    	Signature() {}
    	Signature(const string& h, const string& s) {
    		mH = h;
    		mS = s;
    	}
    	~Signature() {}
    
    public:
    	string getH() const { return mH; }
    	string getS() const { return mS; }
    
    private:
    	string mH;
    	string mS;
    };
    
    
    #endif
    

    签名算法实现

    按照签名流程,实现签名算法:

    
    Signature SM9::sign(const string& masterPublicKey, const string& prikey, const string& data)
    {
    	Signature signature;
    	bool hasException = true;
    	string h, s, sw;
    	ecn2 Ppubs;
    	epoint* dsa = NULL;
    	epoint* S = NULL;
    	ZZN12 g;
    	ZZN12 w;
    	big h2 = NULL;
    	big r = NULL;
    	big l = NULL;
    	big tmp = NULL;
    	big zero = NULL;
    
    #ifdef SELF_CHECK
    	string gHex, rHex, wHex, h2Hex;
    #endif
    
    	if( !mIsInit ) {
    		mErrorNum = SM9_ERROR_NOT_INIT;
    		throw exception(getErrorMsg().c_str());
    	}
    
    	Parameters::init_ecn2(Ppubs);
    	Parameters::init_big(h2);
    	Parameters::init_big(r);
    	Parameters::init_big(l);
    	Parameters::init_big(tmp);
    	Parameters::init_big(zero);
    	Parameters::init_epoint(dsa);
    	Parameters::init_epoint(S);
    
    	// Step1 : g = e(P1, Ppub-s)
    	Parameters::cin_ecn2_byte128(Ppubs, masterPublicKey.c_str());
    	if( !ZZN12::calcRatePairing(g, Ppubs, Parameters::param_P1, Parameters::param_t, Parameters::norm_X) ) {
    		mErrorNum = SM9_ERROR_CALC_RATE;
    		goto END;
    	}
    
    #ifdef SELF_CHECK
    	gHex = YY::YHex::bin2Hex(g.toByteArray());
    #endif
    
    	while( true ) {
    #ifdef SELF_CHECK
    		rHex = YY::YHex::hex2bin("033C8616B06704813203DFD00965022ED15975C662337AED648835DC4B1CBE");
    		Parameters::cin_big(r, rHex.c_str(), rHex.length());
    #else
    		// Step2: generate r
    		bigrand(Parameters::param_N, r);
    #endif
    
    	// Step3 : calculate w=g^r
    		w = g.pow(r);
    		sw = w.toByteArray();
    
    #ifdef SELF_CHECK
    		wHex = YY::YHex::bin2Hex(sw);
    #endif
    
    	// Step4 : calculate h=H2(M||w,N)
    		h = KGC::H2(data, sw);
    		Parameters::cin_big(h2, h.c_str(), h.length());
    
    #ifdef SELF_CHECK
    		h2Hex = YY::YHex::bin2Hex(h);
    #endif
    
    	// Step5 : l=(r-h)mod N
    		subtract(r, h2, l);
    		divide(l, Parameters::param_N, tmp);
    		while( mr_compare(l, zero) < 0 )
    			add(l, Parameters::param_N, l);
    		if( mr_compare(l, zero) != 0 )
    			break;
    	}
    
    	// Step6 : S=[l]dSA=(xS,yS)
    	Parameters::cin_epoint(dsa, prikey.c_str());
    	ecurve_mult(l, dsa, S);
    	s = Parameters::cout_epoint(S);
    
    	// Step7 : signature=(h,s)
    	signature = Signature(h, s);
    
    	hasException = false;
    
    END:
    	Parameters::release_epoint(dsa);
    	Parameters::release_epoint(S);
    	Parameters::release_ecn2(Ppubs);
    	Parameters::release_big(h2);
    	Parameters::release_big(r);
    	Parameters::release_big(l);
    	Parameters::release_big(tmp);
    	Parameters::release_big(zero);
    
    	if( hasException ) {
    		throw exception(getErrorMsg().c_str());
    	}
    	return signature;
    }
    

    验签算法流程

    SM9标准文档中描述的验签算法流程如下所示:
    这里写图片描述
    其流程为:
    这里写图片描述

    根据算法描述,定义接口函数:

    	/**
    	* 验签
    	*
    	* @param masterPublicKey 签名主公钥
    	* @param prikey 用户ID
    	* @param signature 签名值
    	* @param data 待签数据
    	* @return true-验签成功;false-验签失败
    	* @throw std::exception SM9_ERROR_NOT_INIT | SM9_ERROR_CALC_RATE | 
    	* SM9_ERROR_VERIFY_H_OUTRANGE | SM9_ERROR_VERIFY_S_NOT_ON_G1 | SM9_ERROR_VERIFY_H_VERIFY_FAILED
    	*/
    	static bool verify(const string& masterPublicKey, const string& id, const Signature& signature, const string& data);
    

    接口中没有必要提供hid,对于验签算法来说,这是确定的。

    验签算法实现

    
    bool SM9::verify(const string& masterPublicKey, const string& id, const Signature& signature, const string& data)
    {
    	bool result = false;
    	bool hasException = true;
    	big NSub1 = NULL;
    	big one = NULL;
    	big h = NULL;
    	epoint* S = NULL;
    	ecn2 Ppubs;
    	ecn2 P;
    	ZZN12 g;
    	ZZN12 t;
    	ZZN12 u;
    	ZZN12 w;
    	big h1 = NULL;
    	string sH1, sH2, sw, sH, sS;
    
    	if( !mIsInit ) {
    		mErrorNum = SM9_ERROR_NOT_INIT;
    		throw exception(getErrorMsg().c_str());
    	}
    
    	sH = signature.getH();
    	sS = signature.getS();
    
    #ifdef SELF_CHECK
    	string gHex, rHex, h1Hex, tHex, pHex, uHex, wHex;
    #endif
    
    	Parameters::init_big(NSub1);
    	Parameters::init_big(one);
    	Parameters::init_big(h);
    	Parameters::init_epoint(S);
    	Parameters::init_ecn2(Ppubs);
    	Parameters::init_ecn2(P);
    	Parameters::init_big(h1);
    
    	// Step1 : check if h in the range [1, N-1]
    	decr(Parameters::param_N, 1, NSub1);
    	convert(1, one);
    	Parameters::cin_big(h, sH.c_str(), sH.length());
    	if( (mr_compare(h, one) < 0) | (mr_compare(h, NSub1) > 0) ) {
    		mErrorNum = SM9_ERROR_VERIFY_H_OUTRANGE;
    		goto END;
    	}
    
    	// Step2 : check if S is on G1
    	Parameters::cin_epoint(S, sS.c_str());
    	if( !Parameters::isPointOnG1(S) ) {
    		mErrorNum = SM9_ERROR_VERIFY_S_NOT_ON_G1;
    		goto END;
    	}
    
    	// Step3 : g = e(P1, Ppub-s)
    	Parameters::cin_ecn2_byte128(Ppubs, masterPublicKey.c_str());
    	if( !ZZN12::calcRatePairing(g, Ppubs, Parameters::param_P1, Parameters::param_t, Parameters::norm_X) ) {
    		mErrorNum = SM9_ERROR_CALC_RATE;
    		goto END;
    	}
    
    #ifdef SELF_CHECK
    	gHex = YY::YHex::bin2Hex(g.toByteArray());
    #endif
    
    	// Step4 : calculate t=g^h
    	t = g.pow(h);
    
    #ifdef SELF_CHECK
    	tHex = YY::YHex::bin2Hex(t.toByteArray());
    #endif
    
    	// Step5 : calculate h1=H1(IDA||hid,N)
    	sH1 = KGC::H1(id, HID_SIGN);
    	Parameters::cin_big(h1, sH1.c_str(), sH1.length());
    
    #ifdef SELF_CHECK
    	h1Hex = YY::YHex::bin2Hex(sH1);
    #endif
    
    	// Step6 : P=[h1]P2+Ppubs
    	ecn2_copy(&Parameters::param_P2, &P);
    	ecn2_mul(h1, &P);
    	ecn2_add(&Ppubs, &P);
    	ecn2_norm(&P);
    
    #ifdef SELF_CHECK
    	pHex = YY::YHex::bin2Hex(Parameters::cout_ecn2(P));
    #endif
    
    	// Step7 : u=e(S,P)
    	if( !ZZN12::calcRatePairing(u, P, S, Parameters::param_t, Parameters::norm_X) ) {
    		mErrorNum = SM9_ERROR_CALC_RATE;
    		goto END;
    	}
    
    #ifdef SELF_CHECK
    	uHex = YY::YHex::bin2Hex(u.toByteArray());
    #endif
    
    	// Step8 : w=u*t
    	w = u.mul(t);
    	sw = w.toByteArray();
    
    #ifdef SELF_CHECK
    	wHex = YY::YHex::bin2Hex(sw);
    #endif
    
    	// Step9 : h2=H2(M||w,N)
    	sH2 = KGC::H2(data, sw);
    	if( sH2.compare(sH) == 0 ) {
    		result = true;
    	}  else {
    		mErrorNum = SM9_ERROR_VERIFY_H_VERIFY_FAILED;
    	}
    
    	hasException = false;
    END:
    	Parameters::release_big(NSub1);
    	Parameters::release_big(one);
    	Parameters::release_big(h);
    	Parameters::release_epoint(S);
    	Parameters::release_ecn2(Ppubs);
    	Parameters::release_ecn2(P);
    	Parameters::release_big(h1);
    
    	if( hasException ) {
    		throw exception(getErrorMsg().c_str());
    	}
    	return result;
    }
    

    由于验签函数返回类型是bool,因此验签失败后,可以通过getErrorMsg获取错误信息。

    展开全文
  • 国密SM9算法C++实现之六:加密解密算法 国密SM9算法C++实现之六:加密解密算法 加密算法流程 加密结果值 Cipher.h 加密算法实现 解密算法流程 解密算法实现 加密算法...

    SM9算法C++实现系列目录:

    国密SM9算法C++实现之七:加密解密算法

    加密算法流程

    SM9标准文档中描述的加密算法流程如下所示:
    这里写图片描述

    其流程图为:
    这里写图片描述

    根据算法描述,定义接口函数:

    	/**
    	* 加密
    	*
    	* @param masterPublicKey 加密主公钥
    	* @param id 用户ID
    	* @param data 待加密数据
    	* @param isBaseBlockCipher 指明加密明文的方法:true-分组密码;false-基于KDF的序列密码
    	* @param macKeyLen MAC函数的密钥字节长度,应不少于MAC函数中杂凑函数的杂凑值长度。此处可设置32字节
    	* @return 加密值
    	* @throw std::exception SM9_ERROR_NOT_INIT | SM9_ERROR_CALC_RATE
    	*/
    	static Cipher encrypt(const string& masterPublicKey, const string& id, const string& data, bool isBaseBlockCipher, int macKeyLen);
    

    对于加密和解密算法中的明文加密方法,这里定义isBaseBlockCipher 参数来指示;同时,加解密算法中有两个长度,一个是用分组密码加密时的K1_len,因为使用的是SM4,所以是固定的16字节;另一个是K2_len,这个是MAC函数的密钥长度。按照MAC函数定义来说,这个长度是可以变的,但最好不小于MAC函数中的哈希函数的哈希值长度,这里因为使用的是SM3,所以默认是32字节。此处提供一个macKeyLen参数表示此K2_len长度,可以根据需要去掉该参数。

    加密结果值

    SM9加密结果内部包括C1、C2和C3三个部分,对此,也简单将其封装为一个类。这个封装是可取的,可以方便解密时的数据提取。

    Cipher.h

    
    #ifndef YY_SM9_CIPHER_INCLUDE_H__
    #define YY_SM9_CIPHER_INCLUDE_H__
    
    #pragma once
    
    #include <string>
    using namespace std;
    
    /**
    * 加密值,封装了加密结果,包括C1、C2、C3.
    * @author YaoYuan
    */
    class Cipher {
    public:
    	Cipher() {}
    
    	Cipher(const string& C1, const string& C2, const string& C3) {
    		mC1 = C1;
    		mC2 = C2;
    		mC3 = C3;
    	}
    
    	~Cipher() {}
    
    public:
    	string getC1() const { return mC1; }
    	string getC2() const { return mC2; }
    	string getC3() const { return mC3; }
    
    	/**
    	* 加密数据结构构造函数.
    	* @param cipherData 加密数据,可由{@link #toByteArray()}获得
    	*/
    	static Cipher fromByteArray(const string& cipherData) {
    		string C1 = string(cipherData, 0, 64);
    		string C3 = string(cipherData, 64, 32);
    		string C2 = string(cipherData, 64 + 32, cipherData.length() - 96);
    		return Cipher(C1, C2, C3);
    	}
    
    	string toByteArray() {
    		return mC1 + mC3 + mC2;
    	}
    
    private:
    	string mC1;
    	string mC2;
    	string mC3;
    
    };
    
    
    #endif
    

    加密算法实现

    按照加密流程,实现加密算法:

    Cipher SM9::encrypt(const string& masterPublicKey, const string& id, const string& data, bool isBaseBlockCipher, int macKeyLen)
    {
    	Cipher cipher;
    	bool hasException = true;
    	big h1 = NULL;
    	big r = NULL;
    	epoint *Ppube = NULL;
    	epoint *QB = NULL;
    	epoint *C1 = NULL;
    	ZZN12 g;
    	ZZN12 w;
    	string sC1, sC2, sC3, sW, bufferZ, sK, sK1, sK2, tmp, hashH1;
    	int klen = 0;
    	int k1len = 16; // key length for sm4
    	int k2len = macKeyLen;
    
    #ifdef SELF_CHECK
    	string hashH1Hex, QBHex, rHex, C1Hex, C2Hex, C3Hex, gHex, wHex, K1Hex, K2Hex;
    #endif
    
    	if( !mIsInit ) {
    		mErrorNum = SM9_ERROR_NOT_INIT;
    		throw exception(getErrorMsg().c_str());
    	}
    
    	Parameters::init_big(h1);
    	Parameters::init_epoint(Ppube);
    	Parameters::init_epoint(QB);
    	Parameters::init_epoint(C1);
    	Parameters::init_big(r);
    
    	hashH1 = KGC::H1(id, HID_ENCRYPT);
    	Parameters::cin_big(h1, hashH1.c_str(), hashH1.length());
    	Parameters::cin_epoint(Ppube, masterPublicKey.c_str());
    
    #ifdef SELF_CHECK
    	hashH1Hex = YY::YHex::bin2Hex(hashH1);
    #endif
    
    	// Step1 : QB=[H1(IDB||hid, N)]P1+Ppub-e
    	ecurve_mult(h1, Parameters::param_P1, QB);
    	ecurve_add(Ppube, QB);
    	
    #ifdef SELF_CHECK
    	QBHex = YY::YHex::bin2hex(Parameters::cout_epoint(QB));
    #endif
    
    	while( true ) {
    #ifdef SELF_CHECK
    		rHex = YY::YHex::hex2bin("AAC0541779C8FC45E3E2CB25C12B5D2576B2129AE8BB5EE2CBE5EC9E785C");
    		Parameters::cin_big(r, rHex.c_str(), rHex.length());
    #else
    		// Step2: generate r
    		bigrand(Parameters::param_N, r);
    #endif
    
    		// Step3 : C1=[r]QB
    		ecurve_mult(r, QB, C1);
    		sC1 = Parameters::cout_epoint(C1);
    
    #ifdef SELF_CHECK
    		C1Hex = YY::YHex::bin2Hex(sC1);
    #endif
    
    		// Step4 : g=e(Ppub-e, P2)
    		if( !ZZN12::calcRatePairing(g, Parameters::param_P2, Ppube, Parameters::param_t, Parameters::norm_X) ) {
    			mErrorNum = SM9_ERROR_CALC_RATE;
    			goto END;
    		}
    
    #ifdef SELF_CHECK
    		gHex = YY::YHex::bin2Hex(g.toByteArray());
    #endif
    
    		// Step5 : calculate w=g^r
    		w = g.pow(r);
    		sW = w.toByteArray();
    
    #ifdef SELF_CHECK
    		wHex = YY::YHex::bin2Hex(sW);
    #endif
    
    		// Step6_1 : K = KDF(C1 || w || IDB, klen)
    		if( isBaseBlockCipher ) {
    			klen = k1len + k2len;
    		} else {
    			klen = data.length() + k2len;
    		}
    
    		bufferZ.append(sC1);
    		bufferZ.append(sW);
    		bufferZ.append(id);
    		sK = KGC::KDF(bufferZ, klen);
    
    		sK1 = string(sK, 0, sK.length()-k2len);
    		sK2 = string(sK, sK1.length(), sK.length()-sK1.length());
    
    #ifdef SELF_CHECK
    		K1Hex = YY::YHex::bin2Hex(sK1);
    		K2Hex = YY::YHex::bin2Hex(sK2);
    #endif
    
    		if( !isAllZero(sK1) )
    			break;
    	}
    	
    	// Step6_2
    	if( isBaseBlockCipher ) {
    		// C2=Enc(K1,M)
    		YY::YCipher sm4Cipher = YY::YCipher(YY::YCipher::SM4, YY::YCipher::ECB, YY::YCipher::PKCS5Padding);
    		sm4Cipher.init(YY::YCipher::ENCRYPT, sK1);
    		sC2 = sm4Cipher.update(data);
    		tmp = sm4Cipher.doFinal();
    		sC2.append(tmp);
    	} else {
    		// C2=M^K1
    		for( int i = 0; i < data.length(); i++ ) {
    			sC2.append(1, data[i] ^ sK1[i]);
    		}
    	}
    	
    	// Step7 : C3=MAC(K2,C2)
    	sC3 = MAC(sK2, sC2);
    
    #ifdef SELF_CHECK
    	C2Hex = YY::YHex::bin2Hex(sC2);
    	C3Hex = YY::YHex::bin2Hex(sC3);
    #endif
    
    	// Step8 : C=C1|C3|C2
    	cipher = Cipher(sC1, sC2, sC3);
    	hasException = false;
    
    END:
    	Parameters::release_big(h1);
    	Parameters::release_big(r);
    	Parameters::release_epoint(Ppube);
    	Parameters::release_epoint(QB);
    	Parameters::release_epoint(C1);
    
    	if( hasException ) {
    		throw exception(getErrorMsg().c_str());
    	}
    	return cipher;
    }
    

    解密算法流程

    SM9标准文档中描述的解密算法流程如下所示:
    这里写图片描述

    其流程为:
    这里写图片描述

    根据算法描述,定义接口函数:

    	/**
    	* 解密
    	*
    	* @param cipher 加密值
    	* @param prikey 用户私钥
    	* @param id 用户ID
    	* @param isBaseBlockCipher 指明加密明文的方法:true-分组密码;false-基于KDF的序列密码
    	* @param macKeyLen MAC函数的密钥字节长度,应不少于MAC函数中杂凑函数的杂凑值长度。此处可设置32字节
    	* @return 原始数据
    	* @throw std::exception SM9_ERROR_NOT_INIT | SM9_ERROR_CALC_RATE | 
    	* SM9_ERROR_DECRYPT_C1_NOT_ON_G1 | SM9_ERROR_DECRYPT_K1_IS_ZERO | SM9_ERROR_DECRYPT_C3_VERIFY_FAILED
    	*/
    	static string decrypt(const Cipher& cipher, const string& prikey, const string& id, bool isBaseBlockCipher, int macKeyLen);
    

    这里的后两个参数在使用时应该和加密时保持一致。

    解密算法实现

    
    std::string SM9::decrypt(const Cipher& cipher, const string& prikey, const string& id, bool isBaseBlockCipher, int macKeyLen)
    {
    	bool hasException = true;
    	string result, sC1, sC2, sC3, sK1, sK2, sK, sW, bufferZ, tmp, u, M;
    	epoint* C1 = NULL;
    	ecn2 de;
    	ZZN12 w;
    	YY::YSM3 sm3Digest;
    	int klen = 0;
    	int k1len = 16; // key length for sm4
    	int k2len = macKeyLen;
    
    #ifdef SELF_CHECK
    	string wHex, K1Hex, K2Hex, uHex, MHex;
    #endif
    
    	if( !mIsInit ) {
    		mErrorNum = SM9_ERROR_NOT_INIT;
    		throw exception(getErrorMsg().c_str());
    	}
    
    	sC1 = cipher.getC1();
    	sC2 = cipher.getC2();
    	sC3 = cipher.getC3();
    	Parameters::init_epoint(C1);
    	Parameters::init_ecn2(de);
    	
    	// Step1 : check if C1 is on G1
    	Parameters::cin_epoint(C1, sC1.c_str());
    	if( !Parameters::isPointOnG1(C1) ) {
    		mErrorNum = SM9_ERROR_DECRYPT_C1_NOT_ON_G1;
    		goto END;
    	}
    
    	// Step2 : w=e(c,de)
    	Parameters::cin_ecn2_byte128(de, prikey.c_str());
    	if( !ZZN12::calcRatePairing(w, de, C1, Parameters::param_t, Parameters::norm_X) ) {
    		mErrorNum = SM9_ERROR_CALC_RATE;
    		goto END;
    	}
    	sW = w.toByteArray();
    
    #ifdef SELF_CHECK
    	wHex = YY::YHex::bin2Hex(sW);
    #endif
    
    	// Step3_1 : K = KDF(C1 || w || IDB, klen)
    	if( isBaseBlockCipher ) {
    		klen = k1len + k2len;
    	} else {
    		klen = sC2.length() + k2len;
    	}
    
    	bufferZ.append(sC1);
    	bufferZ.append(sW);
    	bufferZ.append(id);
    	sK = KGC::KDF(bufferZ, klen);
    
    	sK1 = string(sK, 0, sK.length() - k2len);
    	sK2 = string(sK, sK1.length(), sK.length() - sK1.length());
    
    #ifdef SELF_CHECK
    	K1Hex = YY::YHex::bin2Hex(sK1);
    	K2Hex = YY::YHex::bin2Hex(sK2);
    #endif
    
    	if( isAllZero(sK1) ) {
    		mErrorNum = SM9_ERROR_DECRYPT_K1_IS_ZERO;
    		goto END;
    	}
    
    	// Step3_2
    	if( isBaseBlockCipher ) {
    		// M=Dec(K1,C2)
    		YY::YCipher sm4Cipher = YY::YCipher(YY::YCipher::SM4, YY::YCipher::ECB, YY::YCipher::PKCS5Padding);
    		sm4Cipher.init(YY::YCipher::DECRYPT, sK1);
    		M = sm4Cipher.update(sC2);
    		tmp = sm4Cipher.doFinal();
    		M.append(tmp);
    	} else {
    		// M=C2^K1
    		for( int i = 0; i < sC2.length(); i++ ) {
    			M.append(1, sC2[i] ^ sK1[i]);
    		}
    	}
    
    	// Step4 : u=MAC(K2,C2)
    	u = MAC(sK2, sC2);
    	if( u.compare(sC3) != 0 ) {
    		mErrorNum = SM9_ERROR_DECRYPT_C3_VERIFY_FAILED;
    		goto END;
    	}
    
    #ifdef SELF_CHECK
    	MHex = YY::YHex::bin2Hex(M);
    	uHex = YY::YHex::bin2Hex(u);
    #endif
    
    	// Step5
    	result = M;
    	hasException = false;
    
    END:
    	Parameters::release_epoint(C1);
    	Parameters::release_ecn2(de);
    
    	if( hasException ) {
    		throw exception(getErrorMsg().c_str());
    	}
    	return result;
    }
    
    
    展开全文
  • 国密SM9算法C++实现之七:密钥交换算法 国密SM9算法C++实现之七:密钥交换算法 密钥交换算法流程 密钥交换结果值 密钥协商初始化:keyExchange_init 临时密钥对:TempKeyPair KeyAgreement .h 接口描述...
  • 国密SM9算法C++实现之0:源码下载地址

    千次阅读 热门讨论 2018-11-12 21:24:06
    SM9算法C++实现系列目录: 国密SM9算法C++实现之0:源码下载地址 国密SM9算法C++实现之一:算法简介 国密SM9算法C++实现之二:测试工具 国密SM9算法C++实现之三:椭圆曲线接口、参数初始化 ...
  • RSA加密算法 C++ 实现

    热门讨论 2010-07-29 11:29:05
    RSA加密算法 C++ 实现,RSA公钥加密算法是1977年由Ron Rivest、Adi Shamirh和LenAdleman在(美国麻省理工学院)开发的。RSA取名来自开发他们三者的名字。RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前为止...
  • RSA加密算法c++实现

    千次阅读 2019-03-06 11:40:00
    RSA加密算法c++实现 先码个代码: /************************************************************************* &gt; File Name: RSA.cpp &gt; Author: YB &gt; E-...
  • 国密SM9算法C++实现之五:密钥封装解封算法 国密SM9算法C++实现之五:密钥封装解封算法 密钥封装算法流程 密钥封装值 密钥封装算法实现 密钥解封算法流程 密钥解封算法实现 ...
  • Bresenham画线算法C++

    千次阅读 2016-11-18 15:49:03
    Bresenham画线算法C++ //斜率为0<m<1.0的Bresenham画线算法 #include<stdlib.h> #include<math.h> void Bresenhamline(int x0,int y0,int xEnd,int yEnd) { int dx=fabs(xEnd-x0),dy=fabs(y...
  • 维特比算法C++实现

    千次阅读 2015-07-27 22:53:17
    维特比算法C++实现概述维特比算法用来解决HMM的预测问题(解码decoding),即已知模型HMM和观测序列O=(O1,O2,...On)O=(O_1,O_2,...O_n),求对给定观测序列条件概率P(I/O)P(I/O)的最大状态序列I=(I1,I2,...In)I=(I_1,...
  • 最小生成树算法C++语言实现

    千次阅读 热门讨论 2021-02-14 11:34:26
    最小生成树算法C++语言实现 1. Prim 思想:选择离当前树最近的点来扩充当前树,直至边数为n-1。因为要从候选点中选择距离最近的点,直接实现比较困难,不如转换一下,选择当前最小生成树中的点向外延伸的边中最短的...
  • Pid控制算法-积分分离pid算法C++实现

    千次阅读 2017-04-10 12:02:18
    五 积分分离的PID控制算法C++语言实现 通过三、四两篇文章,基本上已经弄清楚了PID控制算法的最常规的表达方法。在普通PID控制中,引入积分环节的目的,主要是为了消除静差,提高控制精度。但是在启动、结束或大...
  • 六 抗积分饱和的PID控制算法C++语言实现 所谓的积分饱和现象是指如果系统存在一个方向的偏差,PID控制器的输出由于积分作用的不断累加而加大,从而导致执行机构达到极限位置,若控制器输出U(k)继续增大,执行器开度...
  • 算法c++之二叉树广度遍历和深度遍历 1、深度遍历 struct Tree{ int data; struct Tree *lchild,rchild; }BiTree; 先序遍历(中左右) void PreOrderTraverse(BiTree *T) { if(T){ printf("%c ",T->data...
  • PageRank算法C++代码实现标准版

    千次阅读 多人点赞 2014-09-05 17:46:08
    对于PageRank算法,维基百科和网上很多大牛的博客已经讲得很详细了,这里附上一个自己写的PageRank算法C++实现版本
  • 银行家算法C++实现

    万次阅读 多人点赞 2018-04-12 16:37:54
    网上有很多银行家算法的源代码,下面是本人自己写的,基本算法模型参考教材。 介绍 银行家算法(Banker’s Algorithm)是一个避免死锁(Deadlock)的著名算法,是由艾兹格·迪杰斯特拉(Edsger Wybe ...
  • 通常BM算法采用的是坏字符和好后缀算法(eg.,[BM算法](http://www.cnblogs.com/xubenben/p/3359364.html "cnblogs BM算法")),我学习的《数据结构与算法c++版》Adam Drozdek版教材上使用了 全后缀和部分后缀规则,这种...
  • Apriori算法C++实现

    千次阅读 热门讨论 2018-11-30 21:21:30
    最近刚上了数据挖掘这门课,老师讲了两个...在这里给出一个实现找出所有频繁模式集的c++代码,其中主要使用的存储结构是二维数组,有点简陋,凑合着看看。 另外,这个版本是刚写出来初始版本,自连接之后没有修剪步...
  • 银行家算法C++实现(简洁版本)

    千次阅读 2018-06-27 11:06:26
    银行家算法是一个老问题了,这次课设又出现了,看了看网上动辄200+行,一堆东西感到害怕。。。所以自己写了个简单的供大家参考。... 上代码咯/**银行家算法C++实现,2018.6.27 writer:水题小王子 **...
  • 直线段扫描转换算法——Bresenham算法简介以及C++实现 目录 直线段扫描转换算法——Bresenham算法简介以及C++实现 目录 C++实现 C++实现 参考:《计算机图形学 基础教程 第二版 》孙家广、胡事民 编著 #...
  • 国密SM9算法C++实现之二:测试工具

    千次阅读 热门讨论 2018-07-04 22:10:01
    国密SM9算法C++实现之二:测试工具 在网上找了个基于miracle库实现的SM9算法例子,经过完善后写了在win10的vs2015中写了个测试工具,主要的界面功能截图如下。 KGC密钥生成 在上一篇介绍中已经说明,SM9中...
  • LRU算法C++实现

    千次阅读 2019-07-25 16:42:33
    1.算法概述 LRU算法(Leaset Recently used),或者说缓存调度算法。对于软件层面实现的缓存来说,其主要针对的是对磁盘上具有结构性组织的大型文件数据的随机读取。如果程序需要从磁盘上某个存放了一亿条数据的...
  • 高精度棋盘格角点检测及棋盘生长算法c++实现 cornerDetect and Multi-checkerboard automatic detection realize the paper “Automatic Camera and Range Sensor Calibration using a single Shot” Dependencies ...
  • LRU缓存算法c++实现

    千次阅读 2018-07-26 14:09:58
    在如今的项目开发中,缓存是一种必不可少的存储方式,... 本文通过c++简单的实现这种算法,代码不长,但能很好的体现这种思想  思路: map 存储数据 ,实现查找效率O(1),双向链表实现算法逻辑  算法逻辑: 1....
  • kruskal 算法 c++实现

    千次阅读 2018-10-28 12:38:18
    Kruskal是另一个计算最小生成树的算法,其算法原理如下。首先,将每个顶点放入其自身的数据集合中。然后,按照权值的升序来选择边。当选择每条边时,判断定义边的顶点是否在不同的数据集中。如果是,将此边插入最小...
  • 全排列算法C++实现

    千次阅读 2019-06-27 21:49:00
    //摘自算法笔记 #include<iostream> using namespace std; const int maxn=11; int n,P[maxn],hashTable[maxn]={false}; void generateP(int index){ if(index==n+1){//递归边界,已经处理完排列1~n位了 //...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 92,464
精华内容 36,985
关键字:

算法c++

c++ 订阅