java实现线性反馈移位寄存器实例

题目:

3级线性反馈移位寄存器C3=1时可有4种线性反馈函数,设其初始状态为(a1,a2,a3)=(1,0,1),输出由它们得到的密钥流,并分别利用生成的密钥流对明文“0x0123456789ABCDEF”进行加密,输出加密后的结果,再对密文进行解密,输出解密后的结果。

1.分析

相关题目详解:3级线性反馈移位寄存器在C3=1时可有4种线性反馈函数,设其初始状态为(a1,a2,a3)=(1,0,1),求各线性反馈函数的输出序列及周期-CSDN博客

(1)四种可能情况

情况一:C1=0  C2=1,对应反馈函数:f=a2⊕a1

情况二:C1=0  C2=0,对应反馈函数:f=a1

情况三:C1=1  C2=0,对应反馈函数:f=a3⊕a1

情况三:C1=1  C2=1,对应反馈函数:f=a3⊕a2⊕a1

(2)如何得到密钥流

以情况1为例子

解释从初始状态到第1次:

先把a(i)按照i值从大到小的顺序排好,再计算出f=a2⊕a1=0⊕1=1

此时我们把a3到a1的值往右移一位,由表看就是黄色数字转移到绿色数字的位置

原来a3的值会空出来,我们把f值填入(红色数字),以此类推:

a3

a2

a1

输出(a1)

初始状态

1

0

1

\

第1次

1

1

0

1

第2次

1

1

1

0

(3)加密操作

附:题目中的0x代表16进制

密文二进制 = 密钥流与明文分别16进制转为2进制逐比特异或,得到密文流,再将密文流2进制转为16进制

例子:

附:()内是转换的原文

明文(16进制)

密钥流

原16进制

23

34

转2进制

0010(2)0011(3)

0011(3)0100(4)

逐比特异或

0001 0111

密文流2进制转16进制

1(0001) 3(0111)

(4)解密操作

类似:

明文二进制 = 密钥流与密文分别16进制转为2进制逐比特异或,得到明文流,再将明文流2进制转为16进制

2.代码逐步解析

注释里的格式:序号(代码创建顺序)+注解

(1)根据四种情况得到对应密钥流

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);

        //1.生成int数组记录密文流
        int key[]=new int[100];
        //2.flag(1到4代表不同反馈函数:)
        int flag = 0;
        //3.拿到flag
        System.out.println("请输入不同情况(1到4):");
        flag = sc.nextInt();
        //4.生成密钥流
        key = producekey ( flag, key);

    }

    //5.生成密钥流的方法;
    public static int[] producekey (int flag,int key[]){

        //6.创建存储a1到a3值的参数
        int a1 =1; int a2 =0; int a3 =1;
        //7.创建存储反馈函数计算值参数
        int f =0;
        //8.64次for循环,每轮存储输出a1的值,输入反馈函数计算的值
        for(int i =0; i<64; i++){
            //9.存储每轮输出的a1
            key[i]=a1;
            //10.不同flag选择不同反馈函数计算值
            switch (flag){
                case 1: f=a1^a2;break;
                case 2: f=a1;break;
                case 3: f=a1^a3;break;
                case 4: f=a1^a2^a3;break;
            }
            //11.a1到a3值的迭代
            a1=a2;
            a2=a3;
            a3=f;
        }


        return key;
    }

}

(2)加密操作

        //接着之前的主函数

        //4.生成密钥流
        System.out.println("二进制密钥流:");
        producekey (flag, key);
        //12.2进制明文的长度
       int len = clearText16.length()*4;
       //13.创建int数组存储2进制明文,1位16进制转4位2进制
        int clearText2[] = new int[len];
       //14.将16进制明文转换为2进制,用到创建的16转2方法:C16-2
        System.out.println("二进制明文:");
        C16_2(clearText16,clearText2);
        //18.创建存储密文的int数组,以明文长度为变化依据
        int ciphertext[] = new int[clearText16.length()*4];
        //19.密文=密钥与明文异或,用到创建的异或方法:Xor
        System.out.println("2进制密文:");
        Xor(ciphertext,key,clearText2);
        //22.密文2进制转16进制,用到创建的方法:C2_16
        System.out.println("16进制密文:");
        C2_16(key);

}
//用到的方法:

public static void C16_2(String clearText16,int clearText2[]){
        //16.创建字符串base,明文小写转大写,返回每位16进制明文在base其中的位置,就是对应10进制值;k是明文的索引
        String base = "0123456789ABCDEF";
        int k=0;
        for(int i = 0; i < clearText16.length(); i++)
        {
            char ch = clearText16.charAt(i);

            if(ch >= 'a' && ch <= 'f')
            {
                ch = (char)(ch - ('a' - 'A'));
            }

            int t = base.indexOf(ch);
            //17.10进制转2进制数:移位(位运算);无符号右移动;把值存入明文数组

            for(int j = 3; j >= 0; j--)
            {
                clearText2[k]=(t >>> j) & 1;
                System.out.print(clearText2[k]);
                k++;
            }

        }
        System.out.println();
    }


    private static void Xor(int[] result,int[] text1, int[] text2) {
        //21.将明文和密钥每个字节异或,结果放入并输出密文数组
        for (int i = 0; i < text2.length; i++) {
            result[i]=text1[i]^text2[i];
            System.out.print(result[i]);
        }
        System.out.println();
    }


    private static void C2_16(int[] key) {
        //24.s1连接存储int转Sting的值
        String s1=new String();
        //25.for循环将int转Sting存入s1,每4位2进制数转16进制并输出,因parseInt转换过长的会报错
        for(int i=0;i<key.length;i++){
            s1 +=(key[i]+"");

            if((i+1)%4==0&&i!=0){
                //26.substring用来获取每次新转换的四位数
                int x = Integer.parseInt((s1).substring(i-3,i+1), 2);
                String shiliu = Integer.toHexString(x);
                System.out.print(shiliu);
            }

        }
        System.out.println();
    }

(3)解密操作

       //接着之前的主函数,用到的方法都是之前的

       //22.密文2进制转16进制,用到创建的方法:C2_16
        System.out.println("16进制密文:");
        C2_16(key);
        //27.明文=密钥与密文异或,用到创建的异或方法:Xor
        System.out.println("解密得到的二进制明文:");
        Xor(clearText2,ciphertext,key);
        //28.二进制明文转16进制
        System.out.println("解密得到的16进制明文:");
        C2_16(clearText2);
}

3.完整代码

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);

        //1.生成int数组记录密文流,输入String类型明文
        System.out.println("输入16进制明文:");
        String clearText16 = sc.next();
        int key[]=new int[clearText16.length()*4];
        //2.flag(1到4代表不同反馈函数:)
        int flag = 0;
        //3.拿到flag
        System.out.println("请输入不同情况(1到4):");
        flag = sc.nextInt();
        //4.生成密钥流
        System.out.println("二进制密钥流:");
        producekey (flag, key);
        //12.2进制明文的长度
       int len = clearText16.length()*4;
       //13.创建int数组存储2进制明文,1位16进制转4位2进制
        int clearText2[] = new int[len];
       //14.将16进制明文转换为2进制,用到创建的16转2方法:C16-2
        System.out.println("二进制明文:");
        C16_2(clearText16,clearText2);
        //18.创建存储密文的int数组,以明文长度为变化依据
        int ciphertext[] = new int[clearText16.length()*4];
        //19.密文=密钥与明文异或,用到创建的异或方法:Xor
        System.out.println("2进制密文:");
        Xor(ciphertext,key,clearText2);
        //22.密文2进制转16进制,用到创建的方法:C2_16
        System.out.println("16进制密文:");
        C2_16(key);
        //27.明文=密钥与密文异或,用到创建的异或方法:Xor
        System.out.println("解密得到的二进制明文:");
        Xor(clearText2,ciphertext,key);
        //28.二进制明文转16进制
        System.out.println("解密得到的16进制明文:");
        C2_16(clearText2);




    }

    //23.2进制转16进制方法
    private static void C2_16(int[] key) {
        //24.s1连接存储int转Sting的值
        String s1=new String();
        //25.for循环将int转Sting存入s1,每4位2进制数转16进制并输出,因parseInt转换过长的会报错
        for(int i=0;i<key.length;i++){
            s1 +=(key[i]+"");

            if((i+1)%4==0&&i!=0){
                //26.substring用来获取每次新转换的四位数
                int x = Integer.parseInt((s1).substring(i-3,i+1), 2);
                String shiliu = Integer.toHexString(x);
                System.out.print(shiliu);
            }

        }
        System.out.println();
    }

    //20.创建异或方法
    private static void Xor(int[] result,int[] text1, int[] text2) {
        //21.将明文和密钥每个字节异或,结果放入并输出密文数组
        for (int i = 0; i < text2.length; i++) {
            result[i]=text1[i]^text2[i];
            System.out.print(result[i]);
        }
        System.out.println();
    }

    //15.16进制转2进制的方法
    public static void C16_2(String clearText16,int clearText2[]){
        //16.创建字符串base,明文小写转大写,返回每位16进制明文在base其中的位置,就是对应10进制值;k是明文的索引
        String base = "0123456789ABCDEF";
        int k=0;
        for(int i = 0; i < clearText16.length(); i++)
        {
            char ch = clearText16.charAt(i);

            if(ch >= 'a' && ch <= 'f')
            {
                ch = (char)(ch - ('a' - 'A'));
            }

            int t = base.indexOf(ch);
            //17.10进制转2进制数:移位(位运算);无符号右移动;把值存入明文数组

            for(int j = 3; j >= 0; j--)
            {
                clearText2[k]=(t >>> j) & 1;
                System.out.print(clearText2[k]);
                k++;
            }

        }
        System.out.println();
    }


    //5.生成密钥流的方法;
    public static void producekey(int flag, int key[]){

        //6.创建存储a1到a3值的参数
        int a1 =1; int a2 =0; int a3 =1;
        //7.创建存储反馈函数计算值参数
        int f =0;
        //8.64次for循环,每轮存储输出a1的值,输入反馈函数计算的值
        for(int i =0; i<64; i++){
            //9.存储并输出每轮输出的a1
            key[i]=a1;
            System.out.print(a1);
            //10.不同flag选择不同反馈函数计算值
            switch (flag){
                case 1: f=a1^a2;break;
                case 2: f=a1;break;
                case 3: f=a1^a3;break;
                case 4: f=a1^a2^a3;break;
            }
            //11.a1到a3值的迭代
            a1=a2;
            a2=a3;
            a3=f;
        }
        System.out.print("\n");


    }

4.四种情况的答案

(1)f=a2⊕a1

输入16进制明文:
0123456789abcdef
请输入不同情况(1到4):
1
二进制密钥流:
1011100101110010111001011100101110010111001011100101110010111001
二进制明文:
0000000100100011010001010110011110001001101010111100110111101111
2进制密文:
1011100001010001101000001010110000011110100001011001000101010110
16进制密文:
b972e5cb972e5cb9
解密得到的二进制明文:
0000000100100011010001010110011110001001101010111100110111101111
解密得到的16进制明文:
0123456789abcdef

(2)f=a1

输入16进制明文:
0123456789abcdef
请输入不同情况(1到4):
2
二进制密钥流:
1011011011011011011011011011011011011011011011011011011011011011
二进制明文:
0000000100100011010001010110011110001001101010111100110111101111
2进制密文:
1011011111111000001010001101000101010010110001100111101100110100
16进制密文:
b6db6db6db6db6db
解密得到的二进制明文:
0000000100100011010001010110011110001001101010111100110111101111
解密得到的16进制明文:
0123456789abcdef

(3)f=a3⊕a1

输入16进制明文:
0123456789abcdef
请输入不同情况(1到4):
3
二进制密钥流:
1010011101001110100111010011101001110100111010011101001110100111
二进制明文:
0000000100100011010001010110011110001001101010111100110111101111
2进制密文:
1010011001101101110110000101110111111101010000100001111001001000
16进制密文:
a74e9d3a74e9d3a7
解密得到的二进制明文:
0000000100100011010001010110011110001001101010111100110111101111
解密得到的16进制明文:
0123456789abcdef

(4)f=a3⊕a2⊕a1

输入16进制明文:
0123456789abcdef
请输入不同情况(1到4):
4
二进制密钥流:
1010101010101010101010101010101010101010101010101010101010101010
二进制明文:
0000000100100011010001010110011110001001101010111100110111101111
2进制密文:
1010101110001001111011111100110100100011000000010110011101000101
16进制密文:
aaaaaaaaaaaaaaaa
解密得到的二进制明文:
0000000100100011010001010110011110001001101010111100110111101111
解密得到的16进制明文:
0123456789abcdef

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值