“流密码(序列密码)与Rc4算法”


       Rc4是一种序列密码,它是一种可变密钥长度、面向字节操作的序列密码,一个明文字节与一个密钥字节相异或产生一个密文字节。


      算法原理:对于n = 8位长的字,即以一个字节为单位,此时N = 256,用从1到256个字节的可变长度密钥初始化一个256个字节的状态矢量arr,arr中的元素arr[0],arr[1],,,arr[255],自始至终置换后的arr包含0~255的所有8比特数,密钥流中的密钥key由arr中256个元素按一定方式选出一个元素来充当;每生成一个key值,arr中的元素就被重新置换一次。


      初始化:

             将arr中的元素初始化成arr[0] = 0,arr[1] = 1,,,,,arr[255] = 255,设密钥的长度为len,对于arr中的每个元素,由密钥K将arr[i]中的元素进行置换,由于只是第数组中的元素进行错乱的排列,数组arr中还包含0~255个元素。


 //初始化的核心代码
 
 for (int i = 0; i < 256; i++)
 {
     arr[i] = i;
     K[i] = key[i % len];
     //K数组是将key中的元素循环排列于数组中
 }
  //将数组中的数据进行错乱排列
 for (int i = 0; i < 256; i++)
 {
     j = (j + arr[i] + K[i]) % 256;
     tmp = arr[i];
     arr[i] = arr[j];
     arr[j] = tmp;
 }


       加密时,将输入的明文与密钥进行异或,解密时,将密文与密钥进行异或。


//加密、解密的核心代码

for (size_t j = 0; j < len; j++)
 {
     x = (x + 1) % 256;
     y = (y + arr[x]) % 256;
     
     tmp = arr[x];
     arr[x] = arr[y];
     arr[y] = tmp;
     
     t = (arr[x] + arr[y]) % 256;
     ptr[j] ^= arr[t];
 }


下面是完整的程序:

//头文件“stream.h”


#pragma once
//序列密码(流密码)

#include <string.h>
void Rc4(char* arr, char* ptr, size_t len)       //进行加密或者解密,arr是密钥,ptr是明文
{
    int x = -1;
    int y = 0;
    int t = 0;
    char tmp = 0;
    for (size_t j = 0; j < len; j++)
   {
       x = (x + 1) % 256;
       y = (y + arr[x]) % 256;
       tmp = arr[x];
       arr[x] = arr[y];
       arr[y] = tmp;
       t = (arr[x] + arr[y]) % 256;
       ptr[j] ^= arr[t];
    }
}

void init(char *arr, char* key, size_t len)     //初始化密钥,(密钥调度算法KSA)
{
    int j = 0;
    char K[256] = { 0 };
    char tmp = 0;
    for (int i = 0; i < 256; i++)
    {
       arr[i] = i;
       K[i] = key[i % len];
       //K数组是将key中的元素循环排列于数组中
     }
 //将数组中的数据进行错乱排列
    for (int i = 0; i < 256; i++)
    {
       j = (j + arr[i] + K[i]) % 256;
       tmp = arr[i];
       arr[i] = arr[j];
       arr[j] = tmp;
    }
}

void menu(char *arr, char* key, char* ptr)    //主菜单
{
    char n, ch;
    char arr1[256] = { 0 };
    printf("**********************************\n");
    printf("*********  ——Rc4算法   *********\n");
    printf("*********  1.加密与解密  *********\n");
    printf("*********  0.退出        *********\n");
    printf("**********************************\n");
    printf("---请选择:");
    scanf("%c", &n);
    switch (n)
    {
     case '1':
         printf("请输入需要加密的明文:");
         fflush(stdin);         //清除缓冲区
         for (int i = 0; i < 256; i++)
        {
            if ((ch = getchar()) != '\n')
           {
               ptr[i] = ch;
            }
            else
           {
               break;
           }
        }
        init(arr, key, strlen(key));
        for (int i = 0; i < 256; i++)          //保存初始化后的arr
       {
           arr1[i] = arr[i];
        }
        
        Rc4(arr, ptr, strlen(ptr));       //加密
        printf("\n输出的密文为:");
        printf("%s", ptr);
        
        Rc4(arr1, ptr, strlen(ptr));     //解密
        printf("\n输出的明文为:");
        printf("%s", ptr);
        break;
    case '0':
        exit(EXIT_FAILURE);
    default:
        break;
    }
}
//源文件stream.cpp

#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>
#include <stdlib.h>
#include "stream.h"

int main()
{
    char arr[256] = { 0 };
    char key[256] = {"zheshiyigemiyao"};
    char ptr[256] = { 0 };
 
    menu(arr, key, ptr);
 
    system("pause");
    return 0;
}