本人写的C#类,该算法完善了《朱明海--维普资讯网--对称加解密算法RC6的C#实现》未完善的源码,以供大家学习!

该RC6加密解密算法如有错误,请大家批评指正。

更多内容请参考:本人写的  C#_RC6加密解密方法 http://download.csdn.net/source/2864830

#region
using System;
using System.Collections.Generic;
using System.Text;

namespace WindowsApplication1
{

class RC6
    {
        /// <summary>
        /// 对称加解密算法RC6的C#实现
        /// 公开维普网_朱明海先生未公布的源码
        /// 程序完善设计者:四川威远_老耙子 先生
        /// 2010-11-28
        /// 本程序只提供了明文长度32的算法。
        /// 如有需要,请与本人联系。
        /// Mail:chscwyyg@163.com 电话:0832-8229211
        /// </summary>
        private string m_sEncryptionKey;                                             //密码方法通过KEY属性返回值
        public string m_sCryptedText;                                                //加密解密字符串返回值
        private int m_nChipherlen;                                                   //密码字节数,控制加密最低为128,最好256,间192,有三种选择种16,24,32
        private const int m_nWord = 32;
        private const int r = 20;
        private const int c = 4;
        private uint[] m_nKeyExpandBox;                                              //系统密钥数组
        uint[] n_WordBox;                                                            //用户私有密钥
        public Encoding Enc_default = Encoding.Unicode;

/// <summary>
        /// 左位移运算函数
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="w"></param>
        /// <returns></returns>
        ///
        public uint ROTL(uint x, uint y, int w)
        { return ((x << (int)(y & (0xFF))) | (x >> (int)(w - (y & (0xFF))))); }//或:return ((x << (int)(y & (w-1))) | (x >> (int)(w - (y & (w-1)))));

/// <summary>
        /// 右位移运算函数
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="w"></param>
        /// <returns></returns>
        public uint ROTR(uint x, uint y, int w)
        { return ((x >> (int)(y & (0xFF))) | (x << (int)(w - (y & (0xFF))))); }//或:return ((x >> (int)(y & (w-1))) | (x << (int)(w - (y & (w-1)))));

/// <summary>
        /// 构造函数
        /// </summary>
        public RC6()
        {
            IV = 16;                                        //如果用户没有设置加密方式系统默认为128位加密
            //                                                IV返回m_nChipherlen
            m_nKeyExpandBox = new uint[8 * m_nChipherlen];  //密钥数组大小为加IV*8
        }
        /// <summary>
        /// 构造函数可输入加密向量
        /// </summary>
        /// <param name="iv"></param>
        public RC6(int iv)
        {
            IV = iv;            //返顺       m_nChipherlen
            this.m_nKeyExpandBox = new uint[8 * m_nChipherlen];
        }
        /// <summary>
        /// 定义一个属性,通过属性输入用户密钥并返回
        /// 存储到m_sEncryptionKey
        /// </summary>
        public string KEY
        {
            get { return this.m_sEncryptionKey; }
            set { this.m_sEncryptionKey = value; }
        }

/// <summary>
        /// 加密向量选择
        /// 128方式IV=16
        /// 192方法IV=24
        /// 256方法IV=32
        /// </summary>
        public int IV
        {
            get { return m_nChipherlen; }
            set { m_nChipherlen = value; }
        }

/// <summary>
        /// 加密向量验证函数
        /// 有错误返回最小或最大的向量设置
        /// </summary>
        /// <returns></returns>
        public int _IV()
        {
            if (m_nChipherlen < 16) m_nChipherlen = 16;
            if (m_nChipherlen > 32) m_nChipherlen = 32;
            return m_nChipherlen;
        }

/// <summary>
        /// string类型Unicode字符集转为字节流char[];
        /// </summary>
        /// <returns></returns>
        private char[] String_Unicode()
        {
            string prssword = this.m_sEncryptionKey;
            prssword = (prssword.Length % m_nChipherlen != 0 ? prssword.PadRight(prssword.Length + (m_nChipherlen - (prssword.Length % m_nChipherlen)), '/0') : prssword);

byte[] asciiBytes = Encoding.Convert(Encoding.Unicode, Encoding.ASCII, Encoding.Unicode.GetBytes(prssword));
            char[] asciiChars = new char[Encoding.ASCII.GetCharCount(asciiBytes, 0, asciiBytes.Length)];             //等价=====char[] asciiChars = new char[asciiBytes.Length];
            Encoding.ASCII.GetChars(asciiBytes, 0, asciiBytes.Length, asciiChars, 0);
            return asciiChars;
        }

/// <summary>
        /// 初始化函数用户密钥
        /// 通过KeySteup函数扩展并混合密钥
        /// </summary>
        ///
        private void KeySteup()
        {
            uint P32 = 0xb7e15163;
            uint Q32 = 0x9e3779b9;
            uint A, B;
            A = B = 0;
            int i, j;
            i = j = 0;

char[] key = String_Unicode();                       密码类型转换,String型转换为char[],下面String_Unicode()函数返回值

n_WordBox = new uint[m_nChipherlen/4];                 //选择  16  or  24 or 32  128,192,256加密方式,4,6,8
            uint temp;

//密钥类型转换  string类型转换为uint
            for (j = 0; j < m_nChipherlen; j++)    //asciiChars[j]作0xFF运算,循环左移,如果 m_nChipherlen=32,第一轮不移位字节占位0-7,第二轮左移8位字节占位8-15, 第三轮位移16位,字节占16-23,    
            {                                      //第四轮位移24位字节占位24-31.第四轮生成一个uint,共循环m_nChipherlen次生成m_nChipherlen/4个Uint, 16只生成4个,24生成6个,32生成8个,每个uint点32位,
                //                                       所以加密的密节数==16时,4*32=加密128位,24时==6*32加密192位,32时==8*32加密256位,这里实现加密方式
                temp = (uint)(key[j] & 0xFF) << (8 * (j % 4));
                n_WordBox[j / 4] += (uint)temp;   //循环四次生成一个uint

/* ========================================================说明位移运算方法===================================================================//
                 *                                                               比方:a=97为01100001,0移位Convert.ToString(97, 2).PadLeft(8, '0'),
                 *                                                               b=98为01100010,左移8后变成占位0110001000000000=25088;
                 *                                                               c=99为01100011,左移16位变成占位011000110000000000000000=6488064
                 *                                                               d=100为01100100,左移24变成占位01100100000000000000000000000000=1677721600
                 *                                                               以上abcd左移运算后是以下情况
                 *                                                               abcd相加后变成了一个Uint数据占32字节等于Convert.ToString(100, 2).PadLeft(8, '0') + Convert.ToString(99, 2).PadLeft(8, '0') +
                 *                                                                                                        Convert.ToString(98, 2).PadLeft(8, '0') + Convert.ToString(97, 2).PadLeft(8, '0');
                 *                                                               a+b+c+d=1684234849,其字节为01100100011000110110001001100001;uint value=1684234849请验证下。
                 *                                                               uint转换为字节 string x=Convert.ToString(uint value,2);
                 */
            }

//密钥扩展                                                              m_nChipherLen=32   or 24 or 16  
            this.m_nKeyExpandBox[0] = P32;                                           //扩展密钥初始化,0位置赋值P32 
            for (j = 1; j < 2 * m_nChipherlen + 4; j++)                              //m_nChipherlen是加密向量,反应加密方式128,192,256三种
            { this.m_nKeyExpandBox[j] = m_nKeyExpandBox[j - 1] + Q32; }

int k = 3 * Math.Max(n_WordBox.Length, 2 * m_nChipherlen + 4);
            for (j = 0, i = 0; k > 0; k--)
            {
                A = ROTL(m_nKeyExpandBox[i] + A + B, 3, m_nWord);                   //混合密钥
                m_nKeyExpandBox[i] = (byte)A;
                B += A;
                B = ROTL(n_WordBox[j] + A + B, A + B, m_nWord);                   //m_nKeyExpandBox[ii]的值混合到用户密钥中                        
                n_WordBox[j] = B;                                                 //这里是仍然是uint,生成新用户密码,32位值。提取见上面方法  [***  1]
                i = (i + 1) % (2 * m_nChipherlen + 4);                              //取模运算确保对应 m_nKeyExpandBox和 n_WordBox数组不越界                    
                j = (j + 1) % n_WordBox.Length;                                   //n_WordBox.Length  分别代表 4,6,8
            }
        }
        //

/// <summary>
        /// 加密函数
        /// </summary>
        /// <param name="str">加密的明文</param>
        /// <param name="prssword">返回的密文</param>
        /// <returns></returns>
        public string Encrypt(string str, string prssword)
        {
            str = (str.Length % 32 != 0 ? str.PadRight(str.Length + (32 - (str.Length % 32)), '/0') : str);//验证明文长度不能小开32,不足补空字符串
            KEY = prssword;                                        //Key属性返回m_sEncryptionKey方法
            KeySteup();                                            //初始化

uint A, B, C, D, T, U, temp; T = U = 0;                 //4个32位循环赋值的uint(A,B,C,D)
            A = B = C = D = 0;
            temp = 0;

byte[] input = Encoding.Unicode.GetBytes(str);             // 输入的明文this.m_slnClearText;明文string为Unicode字符集,每个输入字符均为两字节16位

//以Unicode转换Byte是byte[1]奇数值为0,偶数值为0,2,4,6等等为输入的字符十进制值,所以低位值才是要加密的值,高位不管它,因为它为0.
            char[] chars = new char[Encoding.ASCII.GetCharCount(input, 0, input.Length)];
            Encoding.ASCII.GetChars(input, 0, input.Length, chars, 0);
            byte[] output = new Byte[input.Length];

//                                                    加密的字符串不只128个字符情况该如何, 这需要定义byte多维数据才能实现
            for (int k = 0; k < 4; k++)                           /* 输入明文要求为ASCII,将字节低位进行0xFF运算左移8*k位转换input(uint) */
            {
                A += (uint)(input[2 * k] & 0xFF) << (8 * k);      //第一个元素不移位,填充uint0-7位,第二个左移8位填充8-15,第三个左移16位填充16-23位,第四个左移24位填充24-31位,这样组成一个uint
                B += (uint)(input[2 * k + 8] & 0xFF) << (8 * k);  //第五个位元素填充uint32-39位,六个填充40-47位,七个填充48-55位,八个填充56-63位
                C += (uint)(input[2 * k + 16] & 0xFF) << (8 * k); //第九个位元素填充uint64-71位,十个填充72-79位,十一个填充80-87位,十二个填充88-95位
                D += (uint)(input[2 * k + 24] & 0xFF) << (8 * k); //第十三个位元素填充uint96-103位,十四个填充104-111位,十五个填充112-119位,十六个填充120-127位
            }

/*                                                    扩展密钥数组n_LocExpandBox和A,B,C,D进行基本加密
            */
            //A,B,C,D变量循环赋值,第一次A,B,C,D第二次B,C,D,A,第三次C,D,A,B,以此类推,共循环m_nChipherlen-1次。
            B += m_nKeyExpandBox[0];
            D += m_nKeyExpandBox[1];
            for (int i = 1; i <= m_nChipherlen; i++)              //左移计算并位置换位,矩阵运算
            {
                U = ROTL(D * (2 * D + 1), 5, m_nWord);            //左移5位,这里其实m_nWord没有多少实用价值,因为本类未使用return ((x << (int)(y & (w-1))) | (x >> (int)(w - (y & (w-1)))))
                T = ROTL(B * (2 * B + 1), 5, m_nWord);
                A = ROTL(A ^ T, U, m_nWord) + m_nKeyExpandBox[2 * i];
                C = ROTL(C ^ U, T, m_nWord) + m_nKeyExpandBox[2 * i + 1];
                temp = A;                                         //中间变量temp的值为A
                A = B;                                            //B的值赋值给A,就是B的位置移动到了A
                B = C;                                            //C的值赋值给B,就是C的位置移动到了B
                C = D;                                            //D的值赋值给C,就是D的位置移动到了C
                D = temp;                                         //A的值赋值给D,就是A的位置移动到了D                               
            }

uint[] put = new uint[4];

A += m_nKeyExpandBox[2 * r + 2];
            C += m_nKeyExpandBox[2 * r + 3];

put[0] = A;
            put[1] = B;
            put[2] = C;
            put[3] = D;

//转换A,B,C,D为一个字节组output,并进而转换为string型m_sCrytedText,下面是第一步的逆操作.      
            for (int k = 0; k < 4; k++)
            {
                output[2 * k] = (byte)((put[0] >> 8 * k) & 0xFF);
                output[2 * k + 8] = (byte)((put[1] >> 8 * k) & 0xFF);
                output[2 * k + 16] = (byte)((put[2] >> 8 * k) & 0xFF);
                output[2 * k + 24] = (byte)((put[3] >> 8 * k) & 0xFF);

}

char[] outarrchar = new char[output.Length];
            Encoding.Unicode.GetChars(output, 0, output.Length, outarrchar, 0);
            this.m_sCryptedText = new string(outarrchar, 0, outarrchar.Length);
            byte[] Output1 = Enc_default.GetBytes(this.m_sCryptedText);
            //this.m_sEncryptionKey = "";
            return m_sCryptedText;
        }
        /// <summary>
        /// 解密函数
        /// </summary>
        /// <param name="str">解密的密文</param>
        /// <param name="prssword">解密后的明文</param>
        /// <returns></returns>
        public string Decrypt(string str, string prssword)
        {
            str = (str.Length % 32 != 0 ? str.PadRight(str.Length + (32 - (str.Length % 32)), '/0') : str);//验证密文长度不能小开32,不足补空字符串
            KEY = prssword;                                       //Key属性返回m_sEncryptionKey方法
            KeySteup();                                            //初始化

uint A, B, C, D, T, U, temp; T = U = 0;                //4个32位循环赋值的uint(A,B,C,D)
            A = B = C = D = 0;
            temp = 0;
            byte[] input = Enc_default.GetBytes(str);             // 输入的密文this.m_slnClearText;明文string为Unicode字符集,每个输入字符均为两字节16位

byte[] output = new Byte[input.Length];

for (int k = 0; k < 4; k++)
            {
                A += ((uint)input[2 * k] & 0xFF) << (8 * k);
                B += ((uint)input[2 * k + 8] & 0xFF) << (8 * k);
                C += ((uint)input[2 * k + 16] & 0xFF) << (8 * k);
                D += ((uint)input[2 * k + 24] & 0xFF) << (8 * k);

}

C -= m_nKeyExpandBox[2 * r + 3];
            A -= m_nKeyExpandBox[2 * r + 2];

for (int i = 1; i <= m_nChipherlen; i++)
            {
                temp = D;
                D = C;
                C = B;
                B = A;
                A = temp;
                U = ROTL(D * (2 * D + 1), 5, m_nWord);
                T = ROTL(B * (2 * B + 1), 5, m_nWord);
                C = ROTR(C - m_nKeyExpandBox[2 * (m_nChipherlen - i) + 3], T, m_nWord) ^ U;
                A = ROTR(A - m_nKeyExpandBox[2 * (m_nChipherlen - i) + 2], U, m_nWord) ^ T;
            }
            D -= m_nKeyExpandBox[1];
            B -= m_nKeyExpandBox[0];

//转换A,B,C,D为一个字节组output,并进而转换为string型m_sCrytedText,下面是第一步的逆操作.

for (int k = 0; k < 4; k++)
            {
                output[2 * k] = (byte)((A >> (8 * k)) & 0xFF);
                output[2 * k + 8] = (byte)((B >> (8 * k)) & 0xFF);
                output[2 * k + 16] = (byte)((C >> (8 * k)) & 0xFF);
                output[2 * k + 24] = (byte)((D >> (8 * k)) & 0xFF);
            }
            char[] outarrchar = new char[Enc_default.GetCharCount(output, 0, output.Length)];
            Enc_default.GetChars(output, 0, output.Length, outarrchar, 0);
            this.m_sCryptedText = new string(outarrchar, 0, outarrchar.Length);
            byte[] Output1 = Enc_default.GetBytes(this.m_sCryptedText);
            //this.m_sEncryptionKey = "";
            return m_sCryptedText;
        }
    }
}
#endregion

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplication1
{
    public partial class Form1 : Form
    {
        private int round;
        public Form1()
        {
            InitializeComponent();
        }

private void button1_Click(object sender, EventArgs e)
        {
            if (this.textBox1.Text == "") { MessageBox.Show("请输入加密的明文"); this.textBox1.Focus(); return; }
            if (this.textBox3.Text == "") { MessageBox.Show("请输入加密的密钥"); this.textBox3.Focus(); return; }
            RC6 RC = new RC6(round);
            //如果手动输入加密向量RC.IV = -1;请使用RC._IV():函数进行验证。
           
            textBox2.Text = RC.Encrypt(this.textBox1.Text, this.textBox3.Text);
            comboBox1.Enabled = false; comboBox1.ForeColor = System.Drawing.SystemColors.WindowText;
            textBox2.Enabled = false; textBox2.ForeColor = System.Drawing.SystemColors.WindowText;
            textBox3.Enabled = false; textBox3.ForeColor = System.Drawing.SystemColors.WindowText;
        }

private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            string str = this.comboBox1.Text;
            switch (str)
            {
                case "128位加密": round = 16; break;
                case "192位加密": round = 24; break;
                case "256位加密": round = 32; break;
                default: break;
            }
        }

private void Form1_Load(object sender, EventArgs e)
        {
            comboBox1.SelectedIndex = 0;
        }

private void button2_Click(object sender, EventArgs e)
        {
            RC6 RC = new RC6(round);
            this.label6.Text = RC.Decrypt(this.textBox2.Text, this.textBox3.Text);
            comboBox1.Enabled = true; comboBox1.ForeColor = System.Drawing.SystemColors.WindowText;
            textBox2.Enabled = true; textBox2.ForeColor = System.Drawing.SystemColors.WindowText;
            textBox3.Enabled = true; textBox3.ForeColor = System.Drawing.SystemColors.WindowText;
        }
    }
}

实现加解密效果图:128位加解密

192位加解密:

256位加解密:

RC6加密解密算法C#实现源码!相关推荐

  1. 【图像加密】 Logistic混沌+Arnold置乱图像加密解密【含Matlab源码 1281期】

    ⛄一.混沌图像加密与解密简介 混沌系统图像加密解密理论部分参考链接: 基于混沌系统的图像加密算法设计与应用 ⛄二.Arnold置乱图像加密解密简介 0 前言 网络已经成为我们传递信息的主要平台, 为我 ...

  2. 【图像加密】基于matlab GUI正交拉丁方置乱+混沌图像加密解密【含Matlab源码 636期】

    ⛄一.正交拉丁方置乱及混沌系统简介 0 引言 随着通讯技术的飞速发展, 越来越多的领域需要传送数字图像信号, 因此信息的传送安全问题显得越来越重要.通常应用于数字图像通信的两种保护技术为:数字水印技术 ...

  3. 还愁不能解密MD5值?简单代码就能实现md5加密解密,内附源码,亲测可用

    众所周知,md5本身是不可逆的,但我们可以使用以下代码中提供的接口进行解密啊!我试了下成功率是非常的高!8位以内的纯数字的md5值都可以解密. php代码 <?php $MiWen = &quo ...

  4. python:实现DES和3DES加解密算法(附完整源码)

    python:实现DES和3DES加解密算法 import sys _pythonMajorVersion = sys.version_info[0]# Modes of crypting / cyp ...

  5. JAVA:实现XXTea加解密算法(附完整源码)

    JAVA:实现XXTea加解密算法 public class XXTEAprivate XXTEA() {}public static byte[] encrypt(byte[] data, byte

  6. C#:实现SM2加解密算法(附完整源码)

    C#:实现SM2加解密算法 public class SM2CryptoUtil {public SM2CryptoUtil(byte[] pubkey, byte[] privkey, Mode m ...

  7. 基于新唐M0的XXTEA加密解密算法源码

    源:基于新唐M0的XXTEA加密解密算法源码 /*--------------------------------------------------------------------------- ...

  8. 【Matlab图像加密】正交拉丁方置乱算法图像加解密【含GUI源码 182期】

    一.代码运行视频(哔哩哔哩) [Matlab图像加密]正交拉丁方置乱算法图像加解密[含GUI源码 182期] 二.matlab版本及参考文献 一.代码运行视频(哔哩哔哩) [Matlab图像处理]自动 ...

  9. 【安全算法之base64】base64加解密的C语言源码实现

    最近,有项目中需要用到base64的加解密,所以用C语言实现了一遍,测试效果还不错,代码量和RAM消耗都比较低,可以提供给大家参考下. #include <stdbool.h> #incl ...

最新文章

  1. 一篇文章告诉你如何成为数据科学家
  2. Tortoise SVN 版本控制常用操作汇总(show log)
  3. 李宏毅机器学习(七)GPT的野望
  4. php 取得文件行数,PHP获取文件行数的方法
  5. GSAP JS基础教程--动画的控制及事件
  6. qscoj:喵哈哈村的烧烤店(阶梯博弈)
  7. mysql 再查询结果的基础上查询(子查询)
  8. 小米高通系列清串号打开写号端口工具_高通刷机工具最新版下载(Qualcomm Product Support Tool) v2.7 官方版_数码资源网...
  9. 工业视觉 五 频闪及抑制频闪
  10. PDF文件如何编辑?这两种方法是我一直在用的
  11. java计算机毕业设计爱心公益网站设计与制作源码+数据库+系统+lw文档+部署
  12. 迅为3A5000_7A2000开发板龙芯国产处理器LoongArch架构
  13. 配置HTTPS,和HTTPS转HTTP
  14. 如Java8的LocalDate与Date相互转换、ZonedDateTime等常用操作包含多个使用示例、Java8时区ZoneId的使用方法、Java8时间字符串解析成类
  15. 【目标跟踪】帧差法结合卡尔曼滤波行人姿态识别【含GUI Matlab源码 1127期】
  16. matlab白化权函数,《灰色系统、白化规律和白化权函数.pdf》-支持高清全文免费浏览-max文档...
  17. 发那科机器人没有码垛指令_FANUC机器人码垛教程
  18. RHCS+Conga+iSCSI+CLVM+GFS实现Web服务的共享存储HA集群
  19. 值得期待!中兴新支点4G多卡聚合技术将融合到新型导播机
  20. 内核模式代码签名走查(一)

热门文章

  1. python编程软件免费吗_Python Mac下载-Python for Mac(Python编程工具) v3.10.0a2免费版
  2. 程序员的职业素养(一)
  3. 中国磷酸市场应用现状规模与需求前景预测报告2022-2028年
  4. 京东登录页面html代码_2019双十一天猫/京东自动获取喵币/金币方法
  5. FPGA专题-相位累加器(DDS)
  6. 新学问教育php,神墨教师的教育梦——让梦想与爱同行
  7. 用python编写一个猜年龄的小程序-知道了这个,你也能写出 Python 趣味小程序
  8. 《Ext JS 6.2实战》节选——迁移管理模版
  9. 初等行变换、初等列变换
  10. c++算法:四数之和---固定两数,用夹逼法