
利用LFSR结构设计的流密钥生成器C++实现
发布日期:2021-05-07 22:59:45
浏览次数:14
分类:原创文章
本文共 3634 字,大约阅读时间需要 12 分钟。
基于LFSR的流密钥生成器
利用2个LFSR,输出30位流密码
#include <stdio.h>#include<stdlib.h>/*两个寄存器的位数 */#define R1MASK 0x1F /* 5 bits, numbered 0..4 */#define R2MASK 0x0F /* 4 bits, numbered 0..3 *//* 每个寄存器的中间比特 */#define R1MID 0x02 /* bit 2 */#define R2MID 0x02 /* bit 2 *//* 回归标志,用于钟控轮转寄存器*/ /* 特征多项式*/ /*f(x)=x^5+x^4+1;f(x)=x^4+x^3+1. */#define R1TAPS 0x18 /* bits 4,3 */#define R2TAPS 0x0C /* bits 3,2 */ /* 输出标记,用于生成输出 */#define R1OUT 0x10 /* bit 4 (the high bit) */#define R2OUT 0x08 /* bit 3 (the high bit) */typedef unsigned char byte;typedef unsigned int word;typedef word bit;/* 计算移位后填入值 */bit parity(word x) { x ^= x >> 8; x ^= x >> 4; x ^= x >> 2; x ^= x >> 1; return x & 1;}/* 钟控单个寄存器 */word clockone(word reg, word mask, word taps) { word t = reg & taps; reg = (reg << 1) & mask; reg |= parity(t); return reg;}/* 两个钟控寄存器 */word R1, R2;byte m[8] = { 0X01,0x02,0x04,0x08,0x10,0x20,0x40,0x80 };/* 根据钟控规则进行钟控*/void clock() { bit maj = (((R1 & R1MID) >> 1)* ((R2 & R2MID) >> 1)) << 1; if ((R1 & R1MID) == maj) R1 = clockone(R1, R1MASK, R1TAPS); if ((R2 & R2MID) == maj) R2 = clockone(R2, R2MASK, R2TAPS);}/* 对两个都进行钟控,当且仅当用于设置密钥 */void clockallthree() { R1 = clockone(R1, R1MASK, R1TAPS); R2 = clockone(R2, R2MASK, R2TAPS);}/* 生成输出值 */bit getbit() { return parity(R1 & R1OUT) ^ parity(R2 & R2OUT);}/* 进行A5/1密钥设置,这步骤需要64bit密钥和22bit帧数*/void keysetup(byte key[2], word frame) { int i; bit keybit, framebit; /*对移位寄存器置零. */ R1 = R2 = 0; /* 将密钥加载入寄存器, * 优先将每个密钥串的第一个bit作为最低有效位, *对于每个载入的密钥钟控每个寄存器一次 */ for (i = 0; i < 16; i++) { clockallthree(); /* always clock */ keybit = (key[i / 8] >> (i & 7)) & 1; /* The i-th bit of thekey */ R1 ^= keybit; R2 ^= keybit; } /* 将帧数载入移位寄存器,优先最低有效位, 对每个载入的bit钟控寄存器一次 */ for (i = 0; i < 4; i++) { clockallthree(); /* always clock */ framebit = (frame >> i) & 1; /* The i-th bit of the frame #*/ R1 ^= framebit; R2 ^= framebit;; } /*进行不产生输出的20次钟控来融合密钥要素与帧数 */ for (i = 0; i < 20; i++) { clock(); } /* 现在密钥已经完全设置完成. */}/* 生成30bit的密钥流输出*/void run(byte S[]) { int i; /* 将输出缓存置零. */ for (i = 0; i <= 30 / 8; i++) S[i] = 0; /* 生成30bit密钥流用于*/ for (i = 0; i < 30; i++) { clock(); S[i / 8] |= getbit() << (7 - (i & 7)); }}void EnCrypt(byte *p,byte * s,int len){ int i = 0, j = 0; while (p[i] != '\0') { j = i * 8 % len; //该块开头对应的密钥bit位 for (int k = j; k < j + 8; k++) { p[i] ^= s[k % (len / 8 + 1)] ^ m[(k % len) % 8]; } i++; }}void test() { byte key[2] = { 0x01, 0x9C }; word frame = 0x34; byte S[4] = {0}; int i, failed = 0,j; keysetup(key, frame); run(S); printf("密钥为: 0x"); for (i = 0; i < 2; i++) printf("%02X", key[i]); printf("\n"); printf("frame number: 0x%06X\n", (unsigned int)frame); printf("\n"); printf("observed output:\n"); printf(" 密钥流为: 0x"); for (i = 0; i < 4; i++) printf("%02X", S[i]); printf("\n\n\n"); byte p[7] = "朱靖宇"; i = j = 0; printf("明文为 :%s\n", p); while (p[i] != '\0') { printf("%0x ", p[i++]); } printf("\n\n"); i = 0; printf(">>>>开始加密<<<<\n"); EnCrypt(p, S, 30); printf("密文为: 0X"); while (p[i] != '\0') { printf(" %02X", p[i]); i++; } printf("\n\n\n"); i = 0; printf(">>>>开始解密<<<<\n"); EnCrypt(p, S, 30); printf("明文为: "); while (p[i] != '\0') { if (i % 2) printf("%c%c", p[i - 1], p[i]); i++; } printf("\n");}int main(void) { test(); return 0;}
发表评论
最新留言
表示我来过!
[***.240.166.169]2025年04月02日 02时03分53秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
方法重写
2019-03-05
Threading Programming Guide(多线程编程指南)
2019-03-05
Java求逆波兰表达式的结果(栈)
2019-03-05
SDWebImage--http图片加载不出来的问题
2019-03-05
Application received signal SIGSEGV
2019-03-05
MySQL删除数据库时的错误(errno: 39)
2019-03-05
关于MySQL连接时出现的错误之一
2019-03-05
Win10 JDK配置环境变量以及为什么需要配置每部分的原因
2019-03-05
ubuntu学习笔记-常用文件、命令以及作用(hosts、vim、ssh)
2019-03-05
SLAM学习笔记-求解视觉SLAM问题
2019-03-05
target加载不出文件的原因之一
2019-03-05
普歌-允异团队-HashMap面试题
2019-03-05
还在一个一个手动安装虚拟机吗?Cobbler自动部署装机一键最小化安装打把游戏就好了
2019-03-05
C 语言顺序表查找和折半查找
2019-03-05
Windows下Python安装与使用
2019-03-05
Font Awesome图标库使用
2019-03-05
程序员应该知道的97件事
2019-03-05
我编程,我快乐—程序员职业规划之道
2019-03-05
谷歌浏览器如何设置不阻止弹窗弹出
2019-03-05
剑指 Offer 29. 顺时针打印矩阵
2019-03-05