算法git仓库地址:https://github.com/qianduanXIAOHAOZI/Flame
最近,忽然对于加密产生了兴趣,研究了一下base64加密算法,便也想自己开发一个加密算法。
首先,要构思这个加密算法的原理,经过思考,我以如下方式进行加密:
我们要知道,c++中char型是一字节,字符串就是char型数据的总集。接着呢,由于一字节为八比特,我们可以四个四个bit分割,将一个char型数据一分为二,分为两个4bit的数据,接着根据一些方法将这些数据映射到a-p这些字符中。
然后,映射方式可以使用一个数组来存储a-p所有的字母,然后使用下标将数据映射成a-p这些字母。
接下来,我们思考一下,我们算法的结构。
毋庸置疑,需要一个encryption和decryption函数用于加密,并且有一数组提供加密映射。
完成构思后,我给它取名为Flame。
接着,我们首先编写头文件。
include/Flame.h
#ifndef FLAME_FLAME_H
#define FLAME_FLAME_H
#include
using std::string;
namespace Flame {
static char table[] = "abcdefghijklmnop";// 映射表
typedef unsigned long UL;
string encryption(string);// 加密
string decryption(string);// 解密
}
#endif //FLAME_FLAME_H
之后,我们开始实现加密函数。
在这之前,我们还要想一个问题:怎么将char型分割为两个4bit的数据?这下,我们就使用到我们的位运算了!
首先,我们举一个char型数据c的例子:
0110 0001
如果我们要分割这个字节,该这么做呢?
第一步,我们取第一个4bit信息,可以通过右移运算,令其右移四位bit完成,就像这样:c >> 4。
然后,获取第二组4bit信息,可以使用与运算进行:c & 00001111 即: c & 15
那么,该怎么映射呢?首先来看一下第二组,由于其前四个bit的值永远是0所以肯定大于等于0并且小于16,我们可以直接映射。
接着就是比较麻烦的第一组了,我们取到以后,还不能直接映射,因为如果加密unicode的字符就会出现负数,但是加上8就可以完美离开负数区域。所以第一组的最终下标映射值为(c >> 4) + 8
这样,我们就可以编写加密代码了:
string Flame::encryption(string s) {
string ret;// 存储密文
for (UL i = 0; i < s.length(); i++) {
char c = s[i];
char first = (c >> 4) + 8;// 获取前4bit
char second = c & 15;// 获取后4bit
// 向密文添加映射值
ret.push_back(table[first]);
ret.push_back(table[second]);
}
return ret;
}
然后是解密代码,和加密算法同理,不过是反一下,首先获取两组4bit的数据,然后每组组减去映射值97,然后将第一组加密时减去的8加上,并左移4位回去,然后第一组和第二组相加,就是明文。所以可以编写代码如下:
string Flame::decryption(string s) {
string ret;
for (UL i = 0; i < s.length(); i += 2) {
char first = s[i];
char second = s[i + 1];
first -= 105;
second -= 97;
first <<= 4;
second += first;
ret.push_back(second);
}
return ret;
}
最后,整合所有代码如下:
include/Flame.h
#ifndef FLAME_FLAME_H
#define FLAME_FLAME_H
#include
using std::string;
namespace Flame {
static char table[] = "abcdefghijklmnop";
typedef unsigned long UL;
string encryption(string);
string decryption(string);
}
#endif //FLAME_FLAME_H
src/Flame.cpp
#include
#include "../include/Flame.h"
string Flame::encryption(string s) {
// char 1 byte
// 8
// 0 0000000
// 符号位 数字位
// 1010 0101
string ret;
for (UL i = 0; i < s.length(); i++) {
char c = s[i];
char first = (c >> 4) + 8;
char second = c & 15;
ret.push_back(table[first]);
ret.push_back(table[second]);
}
return ret;
}
string Flame::decryption(string s) {
string ret;
for (UL i = 0; i < s.length(); i += 2) {
char first = s[i];
char second = s[i + 1];
first -= 105;
second -= 97;
first <<= 4;
second += first;
ret.push_back(second);
}
return ret;
}
[完]



