当前位置: 首页 > news >正文

刷题感想之置换

这篇其实是之前下午讲课时用的

定义:

置换(Permutation是一种将集合元素重新排列的函数,在密码学中经常用来实现加密操作。它是实
现加密操作的常客,像一把神奇的排列钥匙,能够打乱信息的原有顺序,让其变得难以被轻易解读。
置换是一个双射函数,将集合中的元素重新排列
先补充一下单射,满射和双射
单射:
对集合 A 中任意两个不同元素 aa,它们在 B 中的映射结果一定不同(A 中每个元素对应 B 中唯一元 素,B 中没有重复映射),可以简单理解为B集合范围大
满射:
集合 B 中的每一个元素,都能找到 A 中的至少一个元素与之对应
双射:
A 中每个元素对应 B 中唯一元素,且 B 中每个元素都有 A 中唯一元素对应
什么是置换呢?

类别:

置换有很多种顺序,简单的如恒等,顺时针,逆时针等。但是这里讲一些基础的

单置换:
举个例子:
集合{1,2,3},定义置换 σ(1)=2,σ(2)=3,σ(3)=1
这个式子可以用轮换表示法 σ=(1 2 3),圆括号表示循环。这是置换中一般的表示方法
计算方法可以表示为 12, 23, 31
可以用代码:
# 定义置换σ:用字典存储映射关系(键=原元素,值=置换后元素)
sigma = {1: 2, 2: 3, 3: 1}# 函数:应用置换到单个元素
def apply_sigma(x):if x not in sigma:raise ValueError(f"元素{x}不在置换定义域内(必须是1、2、3)")return sigma[x]# 测试单个元素的置换结果
print(apply_sigma(1))  
print(apply_sigma(2))  
print(apply_sigma(3)) 
这是三个元素都进行循环置换,还有一种是部分元素置换,部分元素不变
例如:
集合 {7,8,9} ,定义置换 ρ ρ(7)=8,ρ(8)=7,ρ(9)=9
可以发现,第三个元素9仍未改变,就可以直观地表示为78(9保持不变),用双向箭头
轮换表示法就是(78)(9)(而且这里的9是不变的,不变元素可省略,简记为(78))
# 定义置换τ:用字典存储映射关系
# 键=原元素(1,2,3),值=置换后元素(τ(1)=3, τ(3)=1, τ(2)=2)
tau = {1: 3, 3: 1, 2: 2}# 函数:对单个元素应用置换τ
def apply_tau(x):if x not in tau:raise ValueError(f"元素{x}不在置换定义域内(必须是1、2、3)")return tau[x]# 测试单个元素的置换结果
print(apply_tau(1))  
print(apply_tau(3))  
print(apply_tau(2))  
这是基础简便的置换,还有一个
复合置换:
复合置换是将两个或多个置换按顺序组合执行的操作,核心规则是「从右到左执行—— 先应用右侧的 置换,再将结果代入左侧的置换,最终形成一个新的置换。
比如说定义两个基础置换a=(1,2,3)b=(1,3)(2)如果将这两个置换合并为一个置换,假设ab=a(b(x)),根 据复合置换的先后顺序:
1个元素,先算b(1)=3 ,再算a(3)=1 最终ab(1)=1
2个元素,先算b(2)=2 ,再算a(2)=3 最终ab(2)=3
3个元素:先算b(3)=1 ,再算a(1)=2 最终ab(3)=2
映射关系:ab(1)=1 ab(2)=3 ab(3)=2
轮换表示:(2,3)(1) ,简记为 (2,3)
直观映射:23 1 保持不变)
一个比较麻烦的例子,对于元素{1,2,3,4,5}
根据置换规则,右侧置换先执行12 23 34 45 51
左侧置换13 32 25 54 41
对每个元素整理,15 53 31 22 44,则1531(1,5,3),不变元素可忽略
复合置换的执行有前提:
定义域 / 值域相同(反例最常见):
置换 σ :作用于集合 {1,2,3} σ(1)=2 σ(2)=3 σ(3)=1
置换 τ :作用于集合 {3,4,5} τ(3)=4 τ(4)=5 τ(5)=3
复合尝试:计算 στ(3) τ(3)=4 ,但 σ 的定义域是 {1,2,3} ,没有 4 的映射定义,无法继续算,复合失败。
通俗的讲,两个置换的集合不同,右置换输出(4不在左置换的输入范围(1-3内,衔接断裂。
元素范围没有冲突:
置换 σ :作用于 {A,B,C,D} σ(A)=B σ(B)=A σ(C)=D σ(D)=C (轮换表示: (AB)(CD)
置换 τ :作用于 {A,B,C}τ(A)=C τ(C)=A τ(B)=B
复合尝试:计算 στ(D) τ 的定义域没有 D,无法先对 D 执行 τ 映射,复合失败。
问题:元素 D σ 中存在,但在 τ 中无定义,无法完成τ σ的完整流程
参与复合的是双射(最基本的)
函数 f (不是置换,非双射):作用于 {1,2,3} f(1)=2 f(2)=2 f(3)=1 (非单射:1 2 都映射到 2)
置换 σ :作用于 {1,2,3} σ(1)=2 σ(2)=3 σ(3)=1
复合尝试:计算 σf(1)=σ(2)=3 σf(2)=σ(2)=3 最终映射 1323,出现多对一,不再是置换(置换必须是双射),复合无意义。
核心问题: f 不是双射,导致复合结果失去置换的本质属性,无法形成有效的复合置换。这个其实就不 必多讲了,在开头提到置换的定义的时候就提到过
逆置换:

就是把置换反过来,也可以直接把箭头给反过来即可

# 原置换:1→2,2→3,3→1
p = {1:2, 2:3, 3:1}# 逆置换(键值互换)
p_inv = {v:k for k,v in p.items()}# 应用逆置换的简单函数
def inv(x):return p_inv[x]# 测试逆置换
print(inv(2))  # 1(对应原置换1→2的逆)
print(inv(3))  # 2(对应原置换2→3的逆)
print(inv(1))  # 3(对应原置换3→1的逆)
以具体的题目为例子,new star CTF2025 置换:
打开
前面给的例子之前就提到过,直接解析题。
P1=(1 3 5 7)(2 4 6)(8 10 12 14)
P2=(1 2 3 4 5 6 7)(8 9 10 11 12 13 14)
根据复合置换规则,先P1,后P2,先分别得出
P1映射表
13,24,35,46,57,62,71,810,99,1012,1111,1214,1313,148.
P2映射表
12,23,34,45,56,67,71,89,910,1011,1112,1213,1314,148.
由此得出F映射
14,25,36,47,51,63,72,811,910,1013,1112,128,1314,149
得到F=(1 4 7 2 5)(3 6)(8 11 12)(9 10 13 14)
根据这个例子及规则,这就是要求其逆置换
根据求出来的F,这个是不相交的,求逆置换可以相当于把箭头反过来(不相交就是两个置换间没有共同元素,从而两个置换不能构成复合置换)
则最终得到的是:
15,27,36,41,52,63,74,812,914,109,118,1211,1310,1413.
将数字对应字母:
A -> EB -> GC -> FD -> AE -> BF -> CG -> DH -> LI -> NJ -> IK -> HL -> KM -> J,N -> M
其它的不变。根据密文,得到置换后的结果  
SUCH A SIMPLE PERMUTATION WILL DEFINITELY NOT STUMP YOU.
这个就是答案,只是大小写的问题

应用:

置换在加密算法中的应用很广泛,包括RC4AESDES等,以RC4为例:
在第一,第二阶段都有
密钥调度算法(KSA)阶段:用密钥初始化 S 盒的置换
在初始化S盒后,通过置换,使 S 状态与密钥强关联且具有伪随机性
用密钥填充一个临时数组 K(密钥长度不足 256 则循环填充)
for i in range(256):
# 用密钥计算置换索引 j,完成 S 盒的首次置换
j = (j + S[i] + key[i % key_len]) % 256
S[i], S[j] = S[j], S[i] # 交换(置换核心操作)
举个简单的例子,以四元素S盒为例
[0,1,2,3],密钥为[1,2]
i=0j = (0 + S[0] + K[0]) % 4 = (0 + 0 + 1) %4 =1 交换 S[0] S[1] S 变为 [1, 0, 2, 3]
i=1j = (1 + S[1] + K[1]) %4 = (1 + 0 + 2) %4 =3 交换 S[1] S[3] S 变为 [1, 3, 2, 0]
i=2j = (3 + S[2] + K[2]) %4 = (3 + 2 + 1) %4 =6%4=2 交换 S[2] S[2](不变) S 仍为 [1, 3, 2,
0]
i=3j = (2 + S[3] + K[3]) %4 = (2 + 0 + 2) %4=4%4=0 交换 S[3] S[0] S 变为 [0, 3, 2, 1]
伪随机数生成算法(PRGA):动态置换生成密钥流
i = j = 0
while True:
i = (i + 1) % 256
j = (j + S[i]) % 256
S[i], S[j] = S[j], S[i] # 动态置换 S 盒
t = (S[i] + S[j]) % 256
yield S[t] # 生成密钥流字节
每次生成密钥流前,S 都会被置换(交换 S[i] S[j])
用AI生成一个简单的RC4算法代码:
def rc4_key_schedule(key):
S = list(range(256)) # 初始 S 盒:[0,1,...,255]
j = 0
key_len = len(key)
for i in range(256):
# 用密钥计算置换索引 j,完成 S 盒的首次置换
j = (j + S[i] + key[i % key_len]) % 256
S[i], S[j] = S[j], S[i] # 交换(置换核心操作)
return S
def rc4_prga(S):
i = j = 0
while True:
i = (i + 1) % 256
j = (j + S[i]) % 256
S[i], S[j] = S[j], S[i] # 动态置换 S 盒
t = (S[i] + S[j]) % 256
yield S[t] # 生成密钥流字节
# 示例:用密钥 b"key" 初始化并生成密钥流
key = b"key"
S = rc4_key_schedule(key)
keystream = rc4_prga(S)
# 前 5 个密钥流字节(每次调用 next 都会触发 S 盒置换)
print([next(keystream) for _ in range(5)])

这里就不再过多讲述了,重点是置换思想。像前面提到的恒等,顺时针,逆时针置换道理一样,只是方法不同

http://www.dtcms.com/a/615910.html

相关文章:

  • 2025-11-15-大模型编程工具使用体验
  • 怎么查网站的外链数量零基础网页设计制作培训
  • 网站开发入帐分录广告门网站
  • 长沙网站排名优化自适应网站cms
  • 脚本语言和编译语言 | 区别、优缺点及适用场景分析
  • 可以自己买个服务器做网站吗南通专业企业门户网站设计
  • 信息管理网站开发实验报告高职学院网站建设方案
  • 爱站网官网关键词环境设计专业就业方向
  • 手机在线编程网站发稿计划怎么写
  • 做百度商桥网站建设一个网站首先需要
  • Spring Data JDBC 详解
  • 如何创建一个企业网站青岛建站seo公司
  • 江苏网站开发多少钱南昌建站软件
  • 北京免费模板建站工程公司注册费用
  • 长兴网站建设公司长沙正规制作网站公司
  • 网站设计作业平台软件 项目管理系统
  • 南通网站关键词优化涿州二康
  • 别人做的网站怎么seo优化wordpress4.7安装主题
  • 楚雄网站建设公司网页开发兼职
  • 网站推广开户网络工程师做什么的
  • 【网络工程】修改linux-kali2018-2022版本的ip地址(保姆级图文)
  • 42_FastMCP 2.x 中文文档之FastMCP集成:Auth0 认证指南
  • 做电影网站投资多少钱园区建设网站的方案
  • 米客优品的网站是哪做的wordpress 多梦
  • 武安网站制作了解电商基本知识
  • 住房和城乡建设主管部门网站济南网络科技有限公司有哪些
  • vivo官方网站进入站内优化网站怎么做
  • 如何做php网站政务网站建设云计算中心
  • 东莞阿里网站设计陕西宏远建设集团网站
  • 瀑布流网站后台wordpress配置环境