实现SM4-ECB、CBC、CFB、OFB算法(大数据版)


base_sm4类参考:

实现SM4算法(16字节版)

sm4.h

实现SM4-ECB、CBC、CFB、OFB算法(大数据版)

#pragma once
#include <algorithm>
#include <iostream>
#include "D:/C++/实现SM4算法(16字节版)/base_sm4.h"

constexpr bool SM4_ENCRYPT = 1;             //进行加密运算
constexpr bool SM4_DECRYPT = 0;             //进行解密运算
constexpr unsigned SM4_BLOCK_SIZE = 16;     //每个分组的大小为16字节,32位

class sm4 :
    public base_sm4
{
public:
    /*
    ECB模式的SM4算法
    ECB模式是最早采用的简单模式,它将加密的数据分成若干组,每组的大小跟加密密钥长度相同,然后每组都用相同的密钥进行加密。相同的明文会产生相同的密文。
    每个分组的运算(加密或解密)都是独立的,每个分组加密只需要密钥和明文分组即可,每个分组解密也只需要密钥和密文分组即可。

    in:明文或者密文
    out:存储明文或者密文,要求out有足够的空间,且长度不低于in的长度
    lenght:in的长度
    key:16字节长度的秘钥
    type:指定为加密或者解密
    */
    void sm4Ecb(std::vector<unsigned char>& in, std::vector<unsigned char>& out, const size_t lenght, std::vector<unsigned char>& key, const bool type);
    /*
    CBC模式的SM4算法
    初始向量(或称初向量)是一个固定长度的比特串。一般使用时会要求它是随机数或伪随机数。使用随机数产生的初始向量,使得同一个密钥加密的结果每次都不同,这样攻击者难以对同一把密钥的密文进行破解。
    加密时,第一个明文块和初始向量进行异或后,再用key进行加密,以后每个明文块与前一个分组结果(密文)块进行异或后,再用key进行加密。
    解密时,第一个密文块先用key解密,得到的中间结果再与初始向量进行异或后得到第一个明文分组(第一个分组的最终明文结果),后面每个密文块也是先用key解密,得到的中间结果再与前一个密文分组(注意是解密之前的密文分组)进行异或后得到本次明文分组。
    in:明文或者密文
    out:存储明文或者密文,要求out有足够的空间,且长度不低于in的长度
    lenght:in的长度
    key:16字节长度的秘钥
    ivec:初始向量,16字节
    type:指定为加密或者解密
    */
    void sm4Cbc(std::vector<unsigned char>& in, std::vector<unsigned char>& out, const size_t lenght, std::vector<unsigned char>& key, std::vector<unsigned char>&ivec, const bool type);
    /*
    CFB模式的SM4算法
    也需要初始向量。
    加密第一个分组时,先对初始向量进行加密,得到的中间结果再与第一个明文分组进行异或得到第一个密文分组;加密后面的分组时,把前一个密文分组作为向量先加密,得到的中间结果再与当前明文分组进行异或得到密文分组。
    解密第一个分组时,先对初始向量进行加密运算(注意,用的是加密算法),得到的中间结果再与第一个密文分组进行异或得到明文分组;解密后面的分组时,把上一个密文分组当作向量进行加密运算(注意,用的还是加密算法),得到的中间结果再与本次的密文分组进行异或得到本次的明文分组。
    in:明文或者密文
    out:存储明文或者密文,要求out有足够的空间,且长度不低于in的长度
    lenght:in的长度
    key:16字节长度的秘钥
    ivec:初始向量,16字节
    type:指定为加密或者解密
    */
    void sm4Cfb(std::vector<unsigned char>& in, std::vector<unsigned char>& out, const size_t lenght, std::vector<unsigned char>& key, std::vector<unsigned char>& ivec, const bool type);
    /*
    OFB模式的SM4算法
    也需要初始向量。
    加密第一个分组时,先对初始向量进行加密,得到的中间结果再与第一个明文分组进行异或得到第一个密文分组;加密后面的分组时,把前一个中间结果(前一个分组的向量的密文)作为向量先加密,得到的中间结果再与当前明文分组进行异或得到密文分组。
    解密第一个分组时,先对初始向量进行加密运算(注意用的是加密算法),得到的中间结果再与第一个密文分组进行异或得到明文分组;解密后面的分组时,把上一个中间结果(前一个分组的向量的密文,因为用的依然是加密算法)当作向量进行加密运算(注意用的是加密算法),得到的中间结果再与本次的密文分组进行异或得到本次的明文分组。
    in:明文或者密文
    out:存储明文或者密文,要求out有足够的空间,且长度不低于in的长度
    lenght:in的长度
    key:16字节长度的秘钥
    ivec:初始向量,16字节
    */
    void sm4Ofb(std::vector<unsigned char>& in, std::vector<unsigned char>& out, const size_t lenght, std::vector<unsigned char>& key, std::vector<unsigned char>& ivec);

    //ecb加解密检查
    int sm4ecbcheck();
    //cbc加解密检查
    int sm4cbccheck();
    //cfb加解密检查
    int sm4cfbcheck();
    //ofb加解密检查
    int sm4ofbcheck();
};

View Code

sm4.cpp

实现SM4-ECB、CBC、CFB、OFB算法(大数据版)

#include "sm4.h"
void sm4::sm4Ecb(std::vector<unsigned char> &in, std::vector<unsigned char> &out, const size_t lenght, std::vector<unsigned char> &key, const bool type){
size_t len = lenght;
//判断参数是否为空,以及判断长度是否为16的倍数
if (in.size() == 0 || out.size() == 0 || key.size() == 0 || lenght % SM4_BLOCK_SIZE != 0) {
return;
}
std::vector<unsigned char>::iterator in_iterator = in.begin();
std::vector<unsigned char>::iterator out_iterator = out.begin();
while (len >= SM4_BLOCK_SIZE) {
//SM4加解密的分组大小为128Bit,故对消息进行加解密时,若消息长度过长,则需要进行循环分组加解密。
if (type== SM4_ENCRYPT) {
//加密
this->SM4_Encrypt(key.begin(), in_iterator, out_iterator);
}
else {
this->SM4_Decrypt(key.begin(), in_iterator, out_iterator);
}
len -= SM4_BLOCK_SIZE;                //没处理完一个分组,长度就要减去16
in_iterator += SM4_BLOCK_SIZE;        //原文数据迭代器偏移16字节,即16个char,指向新的未处理的数据
out_iterator += SM4_BLOCK_SIZE;        //结果迭代器也要偏移16字节,即16个char,指向新的未占用的空间
}
}
void sm4::sm4Cbc(std::vector<unsigned char>& in, std::vector<unsigned char>& out, const size_t lenght, std::vector<unsigned char>& key, std::vector<unsigned char>& ivec, const bool type) {
/*
* 这个算法支持in和out指向同一个缓冲区(称为原地加解密),根据CBC模式的原理,加密时不必区分in和out是否相同,而解密时需要区分。
*/
size_t len = lenght;
std::vector<unsigned char> temp(SM4_BLOCK_SIZE, 0);
std::vector<unsigned char>::iterator iv_iterator = ivec.begin();
std::vector<unsigned char> iv_temp(SM4_BLOCK_SIZE, 0);
//判断参数是否为空,以及判断长度是否为16的倍数
if (in.size() == 0 || out.size() == 0 || key.size() == 0 || ivec.size() == 0 || lenght % SM4_BLOCK_SIZE != 0) {
return;
}
if (type == SM4_ENCRYPT) {
//加密
std::vector<unsigned char>::iterator in_iterator = in.begin();
std::vector<unsigned char>::iterator out_iterator = out.begin();
while (len >= SM4_BLOCK_SIZE) {
/*
* 加密时,第一个明文块和初始向量iv进行异或后,再用key进行加密;
* 以后每个明文块与前一个分组结果(密文)块进行异或后,再用key进行加密
* 前一个分组结果(密文)块当做本次iv
*/
for (int i{}; i < SM4_BLOCK_SIZE; ++i) {
out_iterator[i] = in_iterator[i] ^ iv_iterator[i];
}
//用key进行加密
this->SM4_Encrypt(key.begin(), out_iterator, out_iterator);
iv_iterator = out_iterator;            //保存当前结果,以便下一次循环中和明文进行异或运算
len -= SM4_BLOCK_SIZE;                //减去已完成的字节数
in_iterator += SM4_BLOCK_SIZE;        //偏移明文数据的迭代器,指向未加密的数据开头
out_iterator += SM4_BLOCK_SIZE;        //偏移密文数据的迭代器,指向未放置数据的内存
}
}
else {
//解密
std::vector<unsigned char>::iterator in_iterator = in.begin();
std::vector<unsigned char>::iterator out_iterator = out.begin();
//不同的vector的迭代器不能相互比较,哪怕vector的类型、大小等一样,只要迭代器的来源不属于同一个vector,那么就不能比较。
//if (in_iterator != out_iterator) {
if (in.data() != out.data()) {
//in和out属于不同的缓冲区
while (len >= SM4_BLOCK_SIZE) {
//循环分组处理
this->SM4_Decrypt(key.begin(), in_iterator, out_iterator);
for (int i{}; i < SM4_BLOCK_SIZE; ++i) {
out_iterator[i] = out_iterator[i] ^ iv_iterator[i];
}
iv_iterator = in_iterator;
len -= SM4_BLOCK_SIZE;                //减去已完成的字节数
in_iterator+= SM4_BLOCK_SIZE;        //偏移密文数据迭代器,指向还没解密的数据开头
out_iterator += SM4_BLOCK_SIZE;;    //偏移结果数据指针,指向未放置数据的内存
}
}
else {
//in和out属于相同的缓冲区
iv_temp.insert(iv_temp.end(), ivec.begin(), ivec.begin() + SM4_BLOCK_SIZE);
while (len >= SM4_BLOCK_SIZE) {
//暂存本次分组密文,因为in要存放结果明文
temp.insert(temp.end(), in.begin(), in.begin() + SM4_BLOCK_SIZE);
this->SM4_Encrypt(key.begin(), in_iterator, out_iterator);
for (int i{}; i < SM4_BLOCK_SIZE; ++i) {
out_iterator[i] = out_iterator[i] ^ iv_temp[i];
}
iv_temp.clear();
iv_temp.insert(iv_temp.end(), temp.begin(), temp.begin() + SM4_BLOCK_SIZE);
len -= SM4_BLOCK_SIZE;                //减去已完成的字节数
in_iterator += SM4_BLOCK_SIZE;        //偏移密文数据迭代器,指向还没解密的数据开头
out_iterator += SM4_BLOCK_SIZE;;    //偏移结果数据指针,指向未放置数据的内存
}
}
}
}
void sm4::sm4Cfb(std::vector<unsigned char>& in, std::vector<unsigned char>& out, const size_t lenght, std::vector<unsigned char>& key, std::vector<unsigned char>& ivec, const bool type) {
//CFB模式和CBC类似,也需要IV
rsize_t len = lenght;
unsigned char ch{};
std::vector<unsigned char> iv;
//判断参数是否为空,以及判断长度是否为16的倍数
if (in.size() == 0 || out.size() == 0 || key.size() == 0 || ivec.size() == 0 || lenght % SM4_BLOCK_SIZE != 0) {
return;
}
iv.insert(iv.begin(), ivec.begin(), ivec.begin() + SM4_BLOCK_SIZE);
std::vector<unsigned char>::iterator in_iterator = in.begin();
std::vector<unsigned char>::iterator out_iterator = out.begin();
if (type == SM4_ENCRYPT) {
//加密
std::vector<unsigned char>::iterator iv_iterator = iv.begin();
int i{};
while (len--)
{
if (!i) {
//第一次循环才进入这里
this->SM4_Encrypt(key.begin(), iv_iterator, iv_iterator);
}
iv[i] = *(out_iterator++) = *(in_iterator++) ^ iv[i];
i = (i + 1) % SM4_BLOCK_SIZE;
//上面两行代码就很精妙,实现了iv始终在0~SM4_BLOCK_SIZE之间
}
}
else {
//解密
//解密也是使用的SM4_Encrypt
std::vector<unsigned char>::iterator iv_iterator = iv.begin();
int i{};
while (len--)
{
if (!i) {
this->SM4_Encrypt(key.begin(), iv_iterator, iv_iterator);
}
ch = *in_iterator;
*(out_iterator++) = *(in_iterator++) ^ iv[i];
//上面这句代码应该可以换成*(++out_iterator) = *(++in_iterator) ^ iv[i];
iv[i]=ch;
i = (i + 1) % SM4_BLOCK_SIZE;
//上面两行代码就很精妙,实现了iv始终在0~SM4_BLOCK_SIZE之间
}
}
}
void sm4::sm4Ofb(std::vector<unsigned char>& in, std::vector<unsigned char>& out, const size_t lenght, std::vector<unsigned char>& key, std::vector<unsigned char>& ivec) {
size_t len = lenght;
std::vector<unsigned char> iv;
//判断参数是否为空,以及判断长度是否为16的倍数
if (in.size() == 0 || out.size() == 0 || key.size() == 0 || ivec.size() == 0 || lenght % SM4_BLOCK_SIZE != 0) {
return;
}
iv.insert(iv.begin(), ivec.begin(), ivec.begin() + SM4_BLOCK_SIZE);
std::vector<unsigned char>::iterator in_iterator = in.begin();
std::vector<unsigned char>::iterator out_iterator = out.begin();
std::vector<unsigned char>::iterator iv_iterator = iv.begin();
//OFB模式的加密和解密是一致的
int i{};
while (--len)
{
if (!i) {
this->SM4_Encrypt(key.begin(), iv_iterator, iv_iterator);
}
*(++out_iterator) = *(++in_iterator) ^ iv[i];
i = (i + 1) % SM4_BLOCK_SIZE;
}
}
int sm4::sm4ecbcheck(){
int i, len, ret = 0;
std::vector<unsigned char> key{ 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10 };
std::vector<unsigned char> plain{ 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10 };
std::vector<unsigned char> cipher{ 0x68,0x1e,0xdf,0x34,0xd2,0x06,0x96,0x5e,0x86,0xb3,0xe9,0x4f,0x53,0x6e,0x42,0x46 };
std::vector<unsigned char> En_output;
std::vector<unsigned char> De_output;
std::vector<unsigned char> in;
std::vector<unsigned char> out;
std::vector<unsigned char> chk;
En_output.resize(16);    //需要提前准备好充足的空间
this->sm4Ecb(plain, En_output, 16, key, SM4_ENCRYPT);
//比较两个缓冲区的值是否一致
if (std::equal(cipher.begin(), cipher.end(), En_output.begin())) {
std::cout << "ecb enc(len=16) memcmp ok/n";
}
else {
std::cout << "ecb enc(len=16) memcmp failed/n";
std::cout << "En_output:/n";
std::copy(En_output.begin(), En_output.end(), std::ostream_iterator<unsigned>(std::cout, ","));
std::cout << "cipher:/n";
std::copy(cipher.begin(), cipher.end(), std::ostream_iterator<unsigned>(std::cout, ","));
std::cout << "/n";
}
////比较两个缓冲区的值是否一致
//if (memcmp(En_output.data(), cipher.data(), cipher.size())) {
//    puts("ecb enc(len=16) memcmp failed");
//}
//else puts("ecb enc(len=16) memcmp ok");
De_output.resize(SM4_BLOCK_SIZE);    ////需要提前准备好充足的空间
this->sm4Ecb(cipher, De_output, SM4_BLOCK_SIZE, key, SM4_DECRYPT);
//比较两个缓冲区的值是否一致
if (std::equal(plain.begin(), plain.end(), De_output.begin())) {
std::cout << "ecb dec(len=16) memcmp ok/n";
}
else {
std::cout << "ecb dec(len=16) memcmp failed/n";
std::cout << "En_output:/n";
std::copy(De_output.begin(), De_output.end(), std::ostream_iterator<unsigned>(std::cout, ","));
std::cout << "cipher:/n";
std::copy(cipher.begin(), cipher.end(), std::ostream_iterator<unsigned>(std::cout, ","));
std::cout << "/n";
}
//if (memcmp(De_output.data(), plain.data(), SM4_BLOCK_SIZE)) puts("ecb dec(len=16) memcmp failed");
//else puts("ecb dec(len=16) memcmp ok");
len = 32;
for (i = 0; i < 8; i++)
{
//memset(in, i, len);
in.insert(in.end(), len, i);
out.resize(in.size());    //这里是默认了为16的倍数
this->sm4Ecb(in, out, len, key, SM4_ENCRYPT);    //加密
chk.resize(in.size());    //这里是默认了为16的倍数
this->sm4Ecb(out, chk, len, key, SM4_DECRYPT);    //解密
if (std::equal(in.begin(), in.end(), chk.begin())) {
std::cout << "ecb enc(len=" << len << ") memcmp ok/n";
}
else {
std::cout << "ecb enc(len=" << len << ") memcmp failed/n";
}
//if (memcmp(in.data(), chk.data(), len))  printf("ecb enc/dec(len=%d) memcmp failed/n", len);
//else printf("ecb enc/dec(len=%d) memcmp ok/n", len);
len = 2 * len;
in.clear();
}
return 0;
}
int sm4::sm4cbccheck()
{
int i, len, ret = 0;
std::vector<unsigned char> key { 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10 };//密钥
std::vector<unsigned char> iv { 0xeb,0xee,0xc5,0x68,0x58,0xe6,0x04,0xd8,0x32,0x7b,0x9b,0x3c,0x10,0xc9,0x0c,0xa7 }; //初始化向量
std::vector<unsigned char> plain { 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10,0x29,0xbe,0xe1,0xd6,0x52,0x49,0xf1,0xe9,0xb3,0xdb,0x87,0x3e,0x24,0x0d,0x06,0x47 }; //明文
std::vector<unsigned char> cipher { 0x3f,0x1e,0x73,0xc3,0xdf,0xd5,0xa1,0x32,0x88,0x2f,0xe6,0x9d,0x99,0x6c,0xde,0x93,0x54,0x99,0x09,0x5d,0xde,0x68,0x99,0x5b,0x4d,0x70,0xf2,0x30,0x9f,0x2e,0xf1,0xb7 }; //密文
std::vector<unsigned char> En_output;
std::vector<unsigned char> De_output;
std::vector<unsigned char> in;
std::vector<unsigned char> out;
std::vector<unsigned char> chk;
En_output.resize(plain.size());
//sizeof是输出的字节数,对于这里其实就是长度
this->sm4Cbc(plain, En_output, plain.size(), key, iv, SM4_ENCRYPT);    //加密
//比较是否相等
if (std::equal(cipher.begin(), cipher.end(), En_output.begin())) {
std::cout << "cbc enc(len=16) memcmp ok/n";
}
else {
std::cout << "cbc enc(len=16) memcmp failed/n";
std::cout << "En_output:/n";
std::copy(En_output.begin(), En_output.end(), std::ostream_iterator<unsigned>(std::cout, ","));
std::cout << "cipher:/n";
std::copy(cipher.begin(), cipher.end(), std::ostream_iterator<unsigned>(std::cout, ","));
std::cout << "/n";
}
//if (memcmp(En_output, cipher, 16)) puts("cbc enc(len=32) memcmp failed");
//else puts("cbc enc(len=32) memcmp ok");
De_output.resize(cipher.size());
this->sm4Cbc(cipher, De_output, cipher.size(), key, iv, SM4_DECRYPT);
//比较是否相等
if (std::equal(plain.begin(), plain.end(), De_output.begin())) {
std::cout << "cbc dec(len=16) memcmp ok/n";
}
else {
std::cout << "cbc dec(len=16) memcmp failed/n";
std::cout << "En_output:/n";
std::copy(De_output.begin(), De_output.end(), std::ostream_iterator<unsigned>(std::cout, ","));
std::cout << "cipher:/n";
std::copy(plain.begin(), plain.end(), std::ostream_iterator<unsigned>(std::cout, ","));
std::cout << "/n";
}
/*if (memcmp(De_output, plain, SM4_BLOCK_SIZE)) puts("cbc dec(len=32) memcmp failed");
else puts("cbc dec(len=32) memcmp ok");*/
len = 32;
for (i = 0; i < 8; i++)
{
//memset(in, i, len);
in.resize(len, i);
out.resize(len);
this->sm4Cbc(in, out, len, key, iv, SM4_ENCRYPT);
chk.resize(len);
this->sm4Cbc(out, chk, len, key, iv, SM4_DECRYPT);
//比较是否相等
if (std::equal(in.begin(), in.end(), chk.begin())) {
std::cout << "cbc enc/dec(len=" << len << ") memcmp ok/n";
}
else {
std::cout << "cbc enc/dec(len=" << len << ") memcmp failed/n";
std::cout << "En_output:/n";
std::copy(in.begin(), in.end(), std::ostream_iterator<unsigned>(std::cout, ","));
std::cout << "cipher:/n";
std::copy(chk.begin(), chk.end(), std::ostream_iterator<unsigned>(std::cout, ","));
}
//if (memcmp(in, chk, len))  printf("cbc enc/dec(len=%d) memcmp failed/n", len);
//else printf("cbc enc/dec(len=%d) memcmp ok/n", len);
len = 2 * len;
}
return 0;
}
int sm4::sm4cfbcheck()
{
int i, len, ret = 0;
std::vector<unsigned char> key{ 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10 };//密钥
std::vector<unsigned char> iv{ 0xeb,0xee,0xc5,0x68,0x58,0xe6,0x04,0xd8,0x32,0x7b,0x9b,0x3c,0x10,0xc9,0x0c,0xa7 }; //初始化向量
std::vector<unsigned char> in;
std::vector<unsigned char> out;
std::vector<unsigned char> chk;
len = 16;
for (i = 0; i < 9; i++)
{
in.resize(len, i);
out.resize(len);
chk.resize(len);
this->sm4Cfb(in, out, len, key, iv, SM4_ENCRYPT);
this->sm4Cfb(out, chk, len, key, iv, SM4_DECRYPT);
//比较是否相等
if (std::equal(in.begin(), in.end(), chk.begin())) {
std::cout << "cfb enc/dec(len=" << len << ") memcmp ok/n";
}
else {
std::cout << "/ncfb enc/dec(len=" << len << ") memcmp failed";
std::cout << "/nin:";
std::copy(in.begin(), in.end(), std::ostream_iterator<unsigned>(std::cout, ","));
std::cout << "/nout:";
std::copy(out.begin(), out.end(), std::ostream_iterator<unsigned>(std::cout, ","));
std::cout << "/nchk:";
std::copy(chk.begin(), chk.end(), std::ostream_iterator<unsigned>(std::cout, ","));
break;
}
/*if (memcmp(in, chk, len))  printf("cfb enc/dec(len=%d) memcmp failed/n", len);
else printf("cfb enc/dec(len=%d) memcmp ok/n", len);*/
len = 2 * len;
}
return 0;
}
int sm4::sm4ofbcheck()
{
int i, len, ret = 0;
std::vector<unsigned char> key{ 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10 };//密钥
std::vector<unsigned char> iv{ 0xeb,0xee,0xc5,0x68,0x58,0xe6,0x04,0xd8,0x32,0x7b,0x9b,0x3c,0x10,0xc9,0x0c,0xa7 }; //初始化向量
std::vector<unsigned char> in;
std::vector<unsigned char> out;
std::vector<unsigned char> chk;
len = 16;
for (i = 0; i < 9; i++)
{
out.resize(len);
chk.resize(len);
in.resize(len, i);
this->sm4Ofb(in, out, len, key, iv);
this->sm4Ofb(out, chk, len, key, iv);
//比较是否相等
if (std::equal(in.begin(), in.end(), chk.begin())) {
std::cout << "ofb enc/dec(len=" << len << ") memcmp ok/n";
}
else {
std::cout << "/nofb enc/dec(len=" << len << ") memcmp failed";
std::cout << "/nin:";
std::copy(in.begin(), in.end(), std::ostream_iterator<unsigned>(std::cout, ","));
std::cout << "/nout:";
std::copy(out.begin(), out.end(), std::ostream_iterator<unsigned>(std::cout, ","));
std::cout << "/nchk:";
std::copy(chk.begin(), chk.end(), std::ostream_iterator<unsigned>(std::cout, ","));
break;
}
/*if (memcmp(in, chk, len))  printf("ofb enc/dec(len=%d) memcmp failed/n", len);
else printf("ofb enc/dec(len=%d) memcmp ok/n", len);*/
len = 2 * len;
}
return 0;
}

View Code

实现SM4-ECB、CBC、CFB、OFB算法(大数据版).cpp

实现SM4-ECB、CBC、CFB、OFB算法(大数据版)

// 实现SM4-ECB、CBC、CFB、OFB算法(大数据版).cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include "sm4.h"
int main()
{
sm4 s;
s.sm4ofbcheck();
}
// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单
// 入门使用技巧: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件

View Code

 

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/289366.html

(0)
上一篇 2022年9月14日
下一篇 2022年9月14日

相关推荐

发表回复

登录后才能评论