异或

密码学概论

无人久伴 提交于 2020-01-01 15:16:45
1 基本概念(*) 密码学又分为密码编码学(Cryptography)和密码分析学(Cryptanalysis)。 在密码学中,一个密码体制或密码系统是指由明文、密文、密钥、加密算法和解密算法所组成的五元组。 明文是指未经过任何变换处理的原始消息,通常用m(message)或p( plaintext)表示。所有可能的明文有限集组成明文空间,通常用M或P表示。 密文是指明文加密后的消息,通常用c(ciphertext)表示。所有可能的密文有限集组成密文空间.通常用C表示。 密钥是指进行加密或解密操作所需的秘密/公开参数或关键信息,通常用k(key)表示。所有可能的密钥有限集组成密钥空间,通常用K表示。 加密算法是指在密钥的作用下将明文消息从明文空间映射到密文空间的一种变换方法,该变换过程称为加密,通常用字母E表示,即c= EK(m)。 解密算法是指在密钥的作用下将密文消息从密文空间映射到明文空间的一种变换方法,该变换过程称为解密,通常用字母D表示,即m= DK(c)。 2 密码分析学 (1)唯密文攻击(Ciphertext only Attack) (2)已知明文攻击(Known Plaintext Attack) (3)选择明文攻击(Chosen Plaintext Attack) (4)选择密文攻击(Chosen Ciphertext Attack) (5)选择文本攻击

排序算法:快速排序

♀尐吖头ヾ 提交于 2019-12-28 04:11:35
快速排序(Quicksort)是对冒泡排序的一种改进。 在实际中最常用的一种排序算法,速度快,效率高。 它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。 快速排序采用的思想是分治思想。 算法介绍: 设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选用数组的第一个数)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序。值得注意的是,快速排序不是一种稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动。 一趟快速排序的算法是: 1)设置两个变量i、j,排序开始的时候:i=0,j=N-1; 2)以第一个数组元素作为关键数据,赋值给x,即x=rands[0]; 3)从j开始向前搜索,即由后开始向前搜索(j–),找到第一个小于x的值rands[j],将rands[j]和rands[i]互换; 4)从i开始向后搜索,即由前开始向后搜索(i++),找到第一个大于x的rands[i],将rands[i]和rands[j]互换; 5)重复第3、4步,直到i>=j; (3,4步中,没找到符合条件的值,即3中rands[j]不小于x,4中rands

汉明码(Hamming Code)原理及实现

早过忘川 提交于 2019-12-28 01:14:08
汉明码实现原理 汉明码(Hamming Code)是广泛用于内存和磁盘纠错的编码。汉明码不仅可以用来检测转移数据时发生的错误,还可以用来修正错误。(要注意的是,汉明码只能发现和修正一位错误,对于两位或者两位以上的错误无法正确和发现)。 汉明码的实现原则是在原来的数据的插入k位数据作为校验位,把原来的N为数据变为m(m = n +k)位编码。其中编码时要满足以下原则: 2 ^ k - 1 >= m 其中 ( m = n + k ) 这就是Hamming不等式,汉明码规定,我们所得到的m位编码的2^k ( k>=0 && 2^k < m)位上插入特殊的校验码,其余位把源码按顺序放置。 汉明码的编码规则如下: 在新的编码的2^(k - 1)( k >= 0)位上填入0(即校验位) 把新的编码的其余位把源码按原顺序填入 校验位的编码方式为:第k位校验码从则从新的编码的第2^(k - 1)位开始,每计算2^(k - 1)位的异或,跳2^(k - 1)位,再计算下一组2^(k - 1)位的异或,填入2^(k - 1)位,比如: 第1位校验码位于新的编码的第1位(2 ^(1-1) == 1)(汉明码从1位开始),计算1,3,5,7,9,11,13,15,...位的异或,填入新的编码的第1位。 第2位校验码位于新的编码的第2位(2 ^(2-1) == 2),计算2,3,6,7,10,11,14

感知机为啥无法解决异或问题(非线性问题)

被刻印的时光 ゝ 提交于 2019-12-26 23:57:52
感知机又称之为单层神经网络,只能解决线性问题,无法解决非线性问题,异或问题属于非线性问题,所以感知机无法解决异或问题。 注:所有的线性网络都无法解决异或问题。 参考链接:https://blog.csdn.net/yangfeisc/article/details/45486067 来源: CSDN 作者: weixin_38410551 链接: https://blog.csdn.net/weixin_38410551/article/details/103720541

洛谷_P4301 新Nim游戏(线性基)

可紊 提交于 2019-12-26 22:57:51
新Nim游戏 题目链接: https://www.luogu.com.cn/problem/P4301 题意 有n堆火柴,第一次操作第一个人可以直接拿走若干个整堆的火柴,但不能拿完所有堆,第二次操作第二个人可以直接拿走若干个整堆的火柴,同样也不能拿完。之后两个人进行Nim博弈,问在保证第一个人必胜的情况下,第一回合最少拿多少根火柴。 题解: 经过思考可以发现,第一个人是必胜的,只要第一回合结束后,留下的火柴堆中,没有一个非空子集的异或和为0即可。所以只需要第一次将总和尽可能多的火柴堆留在那里,且保证这些火柴堆的任意子集异或不为0。线性基有一个重要的性质就是线性基内的异或集合中不存在0。所以构造一个线性基,使其总和最大即可。 考虑从大到小依次考虑每个元素,如果其能放到集合内,就放进去即可。 # include <cstdio> # include <iostream> # include <cstdlib> # include <cmath> # include <algorithm> # include <ctype.h> # include <cstring> # include <vector> # include <queue> # include <map> # include <iterator> # define dbg(x) cout<<#x<<" = "<<x<

线性基讲解

有些话、适合烂在心里 提交于 2019-12-26 18:40:28
定义 设数集T的值域范围为[1,2^n−1]。 T的线性基是T的一个子集A={a1,a2,a3,...,an}。 A中元素互相xor所形成的异或集合,等价于原数集T的元素互相xor形成的异或集合。 可以理解为将原数集进行了压缩。 性质 1.设线性基的异或集合中不存在0。 2.线性基的异或集合中每个元素的异或方案唯一,其实这个跟性质1是等价的。 3.线性基二进制最高位互不相同。 4.如果线性基是满的,它的异或集合为[1,2^n−1]。 5.线性基中元素互相异或,异或集合不变。 维护 插入 如果向线性基中插入数x,从高位到低位扫描它为1的二进制位。 扫描到第i时,如果ai不存在,就令ai=x否则x=x⊗ai。 x的结局是,要么被扔进线性基,要么经过一系列操作过后,变成了0。 1 bool insert(long long val) 2 { 3 for (int i=60;i>=0;i--) 4 if (val&(1LL<<i)) 5 { 6 if (!a[i]) 7 { 8 a[i]=val; 9 break; 10 } 11 val^=a[i]; 12 } 13 return val>0; 14 } View Code    合并 将一个线性基暴力插入另一个线性基即可。 1 L_B merge(const L_B &n1,const L_B &n2) 2 { 3 L_B ret=n1

使用异或运算交换两个任意类型变量

ε祈祈猫儿з 提交于 2019-12-26 18:21:30
前几天写了一篇文章是在C语言中 使用异或运算交换两个任意类型变量 ,其基础为使用^交换两个整数的算法: a ^= b; b ^= a; a ^= b; 如果你看明白这个算法,就会发现这样的规律: 一个数异或另一个数两次后,该数保持不变。 即: c = a^b; c = c^b; c == a; 这一规律就是使用异或运算对数据及文件进行加密处理的基本原理。 那就先贴下加密算法的代码: bool XorEncrypt(void* bufPtr, unsigned int bufSize, const char* key, unsigned int keySize) { if (!bufPtr || !key || keySize == 0) { return false; } char* ptr = (char*)bufPtr; unsigned int index; for (unsigned int i = 0; i < bufSize; i++) { index = i%keySize; ptr[i] ^= key[index]; } return true; } 代码中 bufPtr为需要加密的数据指针 bufSize为需要加密的数据长度 key为密钥数据指针 keySize 为密钥数据长度 再附上测试代码: void main() { const char* szKey =

【LeetCode OJ 136】Single Number

风格不统一 提交于 2019-12-26 02:13:06
题目链接: https://leetcode.com/problems/single-number/ 题目: Given an array of integers, every element appears twice except for one. Find that single one. Note: Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory? 解题思路:题意为:给定一个数组。仅仅有一个元素出现了一次。其他元素都出现了两次,找出那个仅仅出现一次的数。 能够遍历数组。分别进行异或运算。 注:异或运算: 同样为0,不同为1。遍历并异或的结果就是那个仅仅出现了一次的数。 演示样例代码: public class Solution { public int singleNumber(int[] nums) { int result=nums[0]; for (int i = 1; i < nums.length; i++) { result^=nums[i]; } return result; } } 来源: https://www.cnblogs.com/claireyuancy/p/7064462.html

【leetcode 136】136. Single Number

寵の児 提交于 2019-12-26 02:12:34
要求:给定一个整数数组,除了其中1个元素之外,其他元素都会出现两次。找出这个只出现1次的元素。 例: array =[3,3,2,2,1] 找出元素1. 思路:最开始的想法是用两次for循环,拿数组自身和自身进行匹配查找,如果能匹配到相同的元素,则进行匹配下一个元素。    后来发现运用 ^异或 操作非常简单明了。 两个相应位上比特如果相异,则执行 异或 操作会得到1 比如二进制: 101 ^ 101 得 000 101 ^ 010 得 111 用此方法对数组元素遍历异或, 得出来得结果 就是单一没有配对得元素。 1 public class Solution { 2 public int singleNumber(int[] nums) { 3 int temp = 0; 4 for(int i = 0;i < nums.length;i++){ 5 temp = nums[i] ^ temp; 6 } 7 return temp; 8 } 9 } 来源: https://www.cnblogs.com/magicya/p/6704033.html

leetcode-136-Single Number

﹥>﹥吖頭↗ 提交于 2019-12-26 02:11:26
题目描述: Given an array of integers, every element appears twice except for one. Find that single one. Note: Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory? 要完成的函数: int singleNumber(vector<int>& nums) 说明: 1、给定一组数,这组数中除了有一个元素只出现一次,其他元素都出现了两次,要求输出这个只出现一次的元素的值。 2、时间复杂度O(n),也就是只能从头到尾遍历一次;空间复杂度O(1),只能使用常数级的空间。 3、照这道题目的要求来看,既不能常规做法的定义一个数组,记录每个数出现了几次;也不能双重循环找到出现两次的数,然后把它们都删掉,接着继续遍历,直到最后只剩下出现一次的数。所以这道题目要求只能遍历一遍,那就只能从数学上寻找方法了。 4、这道题目笔者本人想了很长时间,都不知道采用什么数学方法好,直到在discuss中看到大神采用异或(XOR)的做法……以下举例说明为什么异或能够处理这道问题。 举例说明: 先说明一点,所有整数在计算机中都采用二进制的表示方法。以下举两个例子: