微信公众号文章排版设计(微信公众号文章排版设计软件免费)
7552023-08-29
style="text-indent:2em;">各位老铁们好,相信很多人对博客对称排版怎么弄好看都不是特别的了解,因此呢,今天就来为大家分享下关于博客对称排版怎么弄好看以及对称加密如何实现的问题知识,还望可以帮助大家,解决大家的一些困惑,下面一起来看看吧!
本文目录
先把刘海的部分留出来,然后拎起两缕头发,由外侧的头发缠绕内侧的头发,每绕一下,就用下面的头发再抓一缕外侧的头发,由外向内侧缠绕。
以同样的手法一直绕到后脑勺,然后把头发扎紧。
另一侧以同样的手法,扎紧,再调整一下对称度,整个发型就完成啦!
《奸臣》——救赎与解药
130分钟的片长,正常速度看完,没感觉到要快进。
剧情流畅,略显惊悚的旁白切换观影角度到位,结束后意犹未尽,夜晚两点还想着能不能看看评论,与我而言,是好片子了。
任崇载现实中小心谨慎,聪明过人,万般皆算计,轻易不出任何差池,看是对王一心一意的忠臣。然则内心狂放不羁,心态荒诞扭曲,欲不择手段操控天下仅为满足个人私欲。
燕山君现实中嗜血杀戮荒诞,各种奇葩嗜好,各种不可理喻残暴,试问有什么事情是燕山君不敢做的?然而他的内心,电影虽然表露不多,但他的问话“如是昏君之王,你愿意做忠臣以死相谏,还是愿意顺应做奸臣助纣为虐?”想想王位上哪来的真傻子?这个燕山君其实也心似明镜。艺术水平也应该不错,虽然总在画那个啥哈。
任崇载和燕山君两个心理病人活得就像照镜子,像影子兄弟,崇载帮着并看着王一点点的在现实中演绎自己那龌龊扭曲的内心;而王心里偶尔经纬分明则是崇载现实的写照。你是我的里子,我是你的面子。
直到解药出现!
丹熙是幸运的,燕山君是丹熙的药!那样的悲惨遭遇,那样的无望人生,还有活下去的理由吗?当然有,理由就是王啊,每一分每一秒,每一滴泪水汗水,每一瞬隐而不发又惊心动魄的崩溃,都只是为了手刃昏君啊,没有比这更强大的心里支撑与自我救赎。丹熙经历并实现了整个过程,且完成了最后的举刀,虽然仇恨之人未能最终死于自己刀下,过程的圆满也足以让丹熙可以放下了,更何况,因为崇载,她还可以全身而退。不止幸运,何其幸运!也许,这也是她作为崇载的解药的报答吧。
任崇载也是幸运的,有初恋丹熙出现,哪怕绞尽脑汁,各种置于危险而不顾,纵使放弃亲人,拼尽全力送上残命,面具的泪目里也要坚持得到最后的自我救赎,只因为救赎丹熙这件事情才是他的解药!阻止和结束这一切,也才是他自己的解脱。不过总觉得最后集市刀舞的结局过于理想化了。现实多残酷不应该啊。
燕山君,可怜的王!不想去细查历史上他到底经历了什么,对现实世界无比抗拒,只想要安全感,只想睡得着和画画,只想快点结束眼前这一切。可对于一个也许内心清明的王来说,哪怕荒诞分裂扭曲到如此病态,自杀是做不到的,被自己瞧不上的人杀也是不能够的。曾经有半颗解药在眼前一晃而过,王曾两次要求崇载能杀了自己,了结这一切,可被拒绝了。所以,终究只有他是没有解药的。燕山君位高权重,王冠加冕,何其昂贵,普通哪能觅得解药?日月蚀心,且疼着吧!
要拍摄自己橱窗的商品,您需要做好以下准备工作:
1.**准备工具**:您需要一些基本的摄影设备,如相机(如果有的话)、三脚架、照明设备、背景纸或背景布等。
2.**选择背景和布景**:为了让您的商品照片看起来更专业,您需要选择一个干净、整洁的背景。您可以使用背景纸或背景布,或者选择一个实际的墙壁或橱窗作为背景。确保背景的颜色和风格与您的商品搭配。
3.**选择照明设备**:照明对于拍摄商品至关重要。确保使用适当的照明设备,如室内灯、专业闪光灯或反光板。确保您的商品受到均匀、柔和的光线照射。
4.**调整相机设置**:使用适当的相机设置来确保您的照片具有高质量的画质。通常,您需要使用大光圈(如f/2.8或更大)以创建漂亮的背景虚化效果,以及更高的ISO(如800或更高)以获得更好的低光性能。调整相机的曝光、对焦和白平衡等设置,以获得最佳效果。
5.**拍摄照片**:使用三脚架将相机固定在适当的高度和位置。保持稳定的拍摄,避免任何不必要的抖动。根据需要,可以进行多次拍摄以获得最佳效果。
6.**后期处理**:拍摄完成后,您需要使用图像编辑软件(如AdobePhotoshop或Lightroom)对照片进行编辑。这包括调整曝光、对比度、颜色和锐度等,以获得最佳效果。
7.**分享和宣传**:最后,您可以将处理过的照片发布到社交媒体平台、博客或其他在线空间,以便宣传您的商品。
请注意,以上步骤可能因您的拍摄需求和设备而略有不同。在拍摄过程中,多加练习并不断改进您的技巧,以便更好地展示您的商品。
1.对称密码基础
加密是为了防止要传达的内容被别人知道。例如,你如果想在课堂上传小纸条給后位小红说:ilovecoding,但又怕在递纸条的过程中被老师看到,知道了你的心思,于是将每个字母变字母表中的后一个字母(如a变成b,i变成j,z变成a),得到密文:jmpwfdpejoh,这样即老师人拿到这纸条,也不知道你说的是什么。
这就是一个加密的过程,把原本的内容称为明文,一般用p表示;加密后得到的内容称为密文,一般用c表示;而加密的这个过程可以看做是一个加密函数E,即
c=E(p)
E是指Encrypt,函数输入是明文,输出是加密之后的密文。上面的例子中ilovecoding便是明文,jmpwfdpejoh便是密文,而把字母在字母表中向后移动一位的操作就是加密函数。
在小红得到小纸条后,可以根据你加密的方法,将每个字母变成字母表中的前一个字母,就可以从你的密文小纸条得到你要说的内容ilovecoding,心领神会,顺便还会怀疑一下你的脑袋……无论怎样,这个解密的过程就也可以看做是一个解密函数D,即
p=D(c)
D是指Decrypt,函数输入是密文,输出是解密之后的明文。
在这个过程这种,小红能够成功解密小纸条的前提是,你得和她在课前约定好你加密的时候移动的是1位,2位还是几位,不然他就会和老师一样一脸懵逼,不知道你在说啥。你们提前约定好的这个“几位”,就是加密和解密的密钥k,你会根据这个秘钥来进行加密,小红会根据这个秘钥来进行解密。
所以你的传纸条的动作抽象成这个过程:
明文p---->加密函数E---->密文c---->传输---->密文c----->解密函数D---->明文p
或者用公式来表达是:
c=Dk(Ek(c))
用大白话说就是:明文用同一个密钥先加密再解密得到的还是同一个明文(等于没说…)
从这里我们可以总结出加密体质的五个要素:{明文p,密文c,密钥k,加密函数E,解密函数D},对称解密的的意思就是说,加密和解密的密钥是一样的,上面的过程是不是正好很对称呢?
为了方便使用,不用每次自己手动掰手指数字符,你还写了Python程序:
#移位密码
def_move_leter(letter,n):
"""
把字母变为字母表后n位的字母,z后面接a
:paramletter:小写字母
:paramn:要移动的字母
:return:移动的结果
"""
returnchr((ord(letter)-ord('a')+n)%26+ord('a'))
defEncrypt(k,p):
"""
移位密码加密函数E
:paramk:秘钥k,每个字母在字母表中移动k位
:paramp:明文p
:return:密文c
"""
letter_list=list(p.lower())
c=''.join([_move_leter(x,k)forxinletter_list])
returnc
defDecrypt(k,c):
"""
移位密码解密函数D
:paramk:秘钥k,每个字母在字母表中移动k位
:paramc:密文c
:return:明文p
"""
letter_list=list(c.lower())
p=''.join([_move_leter(x,-k)forxinletter_list])
returnp
if__name__=='__main__':
p='ilovecoding'
print('明文:'+p)
print('密文:'+Encrypt(1,p))
print('解密:'+Decrypt(1,Encrypt(1,p)))
assertDecrypt(1,Encrypt(1,p))==p
运行这段代码,就可以看到输出了:
明文:ilovecoding
密文:jmpwfdpejoh
解密:ilovecoding
终于,现在你能和你的小红秘密地传达纸条内容了,迎来全班人羡慕的目光,从此走上人生巅峰,本文到此结束。
…Hey,醒醒…
2.密码分析
面对你俩日益频繁的纸条往来,老师终于坐不住了,他想知道你俩写的到底是啥,于是在某次逮到你递纸条之后,决定下功夫破解你所使用的密码,也就是密码分析。
根据他的了解,以你的水平,最可能用的就是移位密码,但具体每次移动了几位,无法直接观察得出。不过他又一想,你移动的位数顶多是25位,因为,移动26位的效果等于没移动,移27位的效果不就跟移动1位的效果是一样的嘛!这就是说,你的密码只能是0-25中的某一个数字,而不可能是其他的,就这么二十几个秘钥,一个一个试就能知道你写的是啥!
老师果然聪明绝顶,关键是也还会Python,就索性写了一个程序,每次尝试用不同的秘钥来进行解密,并观察解密出来的内容是否有意义:
defanalyze(c):
"""
移位密码分析
:paramc:密文c
:return:
"""
forkinrange(26):
#用不同的秘钥k尝试解密
print('秘钥%d:'%k+Decrypt(k,c))
if__name__=='__main__':
c='jmpwfdpejoh'
analyze(c)
运行程序输出结果为:
秘钥0:jmpwfdpejoh
秘钥1:ilovecoding
秘钥2:hknudbnchmf
秘钥3:gjmtcambgle
...........
逐行观察输出结果,到第二行的时候就能看到原来的明文,也就知道了你要对小红说的内容以及你们所约定的秘钥。面对你冒着巨大风险在课堂上所传递的纸条内容,老师心里可能也是复杂的…
Anyway,你的小秘密已经被老师知道了,此时比较灰心,一直在想,究竟是什么原因致使纸条计划失败?其实原因很明显,各位也看出来了,小明所使用的加密体制中,可用的秘钥太少,或者说秘钥空间太小,别人直接一一列举进行穷搜就能破解,这就提示我们:一个好的加密体制,它的秘钥空间应该是足够大的。
其实,你此次所用的移位密码是古典的加密体制之一,据说凯撒打仗时就用这种方法与将军们联系,所以位移密码也叫凯撒密码(Caesarcipher)。类似的还有代换密码,仿设射密码等等,都是将单个字母替换成别的字母,来达到加密的目的。报纸上的猜谜游戏就经常用这些方法,一般根据字母频率进行破解,有兴趣可以进行进一步的了解。
所以到底要用什么样的加密方法,才能保证我和小红的秘密不被人偷窥呢?
2.1密码分析情形
俗话说,知己知彼,百战不殆,了解破解者的密码分析方法,或许能够帮助我们想出更安全的密码体制。可以在不同的情形下考察密码体制的安全性,一般我们都假设破解者知道我们所使用的密码体制,也就是说,不把密码体制的安全性寄托在加密和解密方法的保密性上,而是放在秘钥上。
破解者的目的就是找出所使用的秘钥,常见的有以下几种攻击情形:
唯密文攻击:破解者拥有密文c。这就是老师破解纸条的情形。
已知明文攻击:破解者拥有一些明文p及其对应的密文c。考虑到实际情形,这个假设是比较合理的,例如破解者获得一封邮件加密后的密文,可以猜测一个词很可能是'hi'或者'dear',这样就可能找到一个明文–密文对。
选择明文攻击:破解者能够指定一个明文p,获得其对应的密文c,较强的假设。
选择密文攻击:破解者指定一个密文c,获得其对应的明文,较强的假设。
天啊,你不禁惊呼,在这么强的假设下,真的会有密码体制能够存活吗?
答案是有,而且这种密码体制已经被广泛应用,甚至可以说无处不在,它就是AES(AdvancedEncryptionStandard)。
3.SPN网络
难道不是要介绍AES吗,怎么会变成SPN网络,这是啥?可以吃吗?
AES、DES等很多现代对称加密方法的核心就是SPN网络,它是代换-置换网络(Substitution-PermutationNetwork)的缩写,是现代对称加密方法设计的蓝本。可以说,了解SPN网络,就基本了解了AES。
很巧的是,这个网络正好是容易理解的。SPN网络的思想很简单:既然加密一次不够安全,那我就加密多次,把第一次加密产生的密文再进行加密,解密的时候我连续进行两次解密就可以了,这样是不是就安全了一些呢?
对于密码体制S1,其加密与解密函数为E1与D1,对于密码体制S2,其加密与解密函数为E2与D2,我构造出一个新的密码体制S3,其加密函数为:
c=E2(E1(p))
解密函数为:
p=D1(D2(c))
记为S3=S1*S2
这样破解S3就可能会困难些。这个想法是不是很直接呢?这个思想在1949年才被提出,而提出者,可能理科生都多少听过他的名字——香农(Shannon)。
注意,不是任何的加密体制都可以这样“乘”起来变得更强,例如对于你的移位密码,嵌套起来还是移位密码(为什么?),没有任何改善,即S1*S1=S1,这样的密码体制被称为幂等的。
如果密码体制不是幂等的,那么多次迭代就可能能够提高安全性,SPN就是使用这种思想,包含多轮的迭代,每轮的操作都是相同的。下面,介绍SPN单轮的操作:
3.1SPN单轮操作
SPN网络是对一定长度的比特进行操作的,在本文中的SPN网络中,一次加密的长度为16个比特,即2字节,也就是说每次加密16比特的明文,输出16比特的密文。
一个SPN网络包含多轮迭代,每轮迭代的操作内容都一样是:异或运算–>分组代换–>单比特置换
3.1.1第一步——异或运算
异或运算是比较常见的二元比特运算,用⊕表示,其规则就是“相同得0,不同得1”:
0⊕0=0
1⊕1=0
1⊕0=1
0⊕1=1
对于比特串,直接按每一位对应进行计算即可以了:
0011⊕1010=1001
异或的有比较有意思的性质:一个比特串亦或另一个比特串两遍,还是等于他自己,即a⊕b⊕b=a,这是因为a⊕b⊕b=a⊕(b⊕b)=a⊕0=a,可以带入一些例子试试看。
SPN网络中,每一轮的第一步就是把输入的比特串w和秘钥k进行亦或:u=w⊕k,如:
0001110000100011=0010011010110111⊕0011101010010100
这一步的目的是根据秘钥对明文进行混淆。如果你只知道输出u而不知道秘钥k,那么你就猜不出实际输入的w是什么,它是什么都可能,而且是等概率的。例如对于1=a⊕b,不告诉你b是0还是1,你就不知道a是什么。而对于和操作,如果知道1=aandb,那么就能确定a与b都是1。
这就是第一步,是不是很简单呢?
3.1.2第二步——分组代换
这一步也很简单,将第一步输出的16比特的串分为4组,每组4比特,即0001110000100011写成0001110000100011。然后对于每组再根据事先所定的表进行代换,代换表长这样:
图1
就拿第一列来说,表的意思是:如果你是0(0000),那么我要把你换成成E(1110),就是一个简单的映射操作。
原比特串长这样:0001110000100011<==>1C23,再对每个字母查表得到:45D1<==>0100010111010001,这样就得到代换后的比特串0100010111010001,完成了第二步。
这个表一般称为S盒(Substitution),这个过程可以用v=S(u)表示,u是第一步异或的结果,也是第二步分组代换的输入,v是第二步的输出。需要注意,S盒的输入和输出一般是非线性的关系。
3.1.3第三步——单比特置换
单比特置换是将16比特中的每一比特,根据P盒(Permutation)移动挪位,这样说很不直观,直接上例子,P盒长这样:
图2
拿第二列来说,表的意思是:第2个比特要挪到第5个比特的位置,举个好看的例子:
0100000000000000置换后为==>0000100000000000
这个例子里面第二个比特的1挪到了第五的位置,而其他位置的比特都是0,挪位置之后还是0。
对于第二部输出的结果1100110111000100,置换后的比特串为0010111000000111,这样就完成了第三步。
这一步可以用W=S(v)表示,v是第二部的输出,也是第三步的输入,W是第三步的输出,P盒置换是一种线性的变换。
这三步放在一起结果如下,建议读者自己计算一遍:
w=0010011010110111
k=0011101010010100
第一步,异或运算:
u=w⊕k=0001110000100011
第二步,分组代换:
v=S(u)=0100010111010001
第三步,单比特置换:
W=P(v)=0010111000000111
可以写成:W=P(S(w⊕k)),这样就完成了一轮迭代,里面用到的参数有k,S盒与P盒,如图(图片来自维基百科):图3
3.2SPN的多轮迭代
弄清楚一轮的流程,SPN整体就很容易明白了,就是一轮一轮的乘起来,上一轮的输出作为这一轮的输入:
w0=x
w1=P(S(w0⊕k1))
w2=P(S(w1⊕k2))
w3=P(S(w2⊕k3))
w4=P(S(w3⊕k4))
y=w4
w0就是16比特的明文,w4是4轮操作后的16比特密文结果,是不是很简单?需要注意的是,每一轮迭代的秘钥k是不一样的,一般是由一个基础秘钥经特定秘钥编排算法生成的,而使用的S盒P盒都是相同的,会提前确定好,并且是公开的。
下图是一个三轮SPN网络的示意图(图片来自维基百科):图4
注意在最后一轮去掉了代换操作,这样做可以使加密算法稍微做一些调整就可以用来进行解密。
OK!SPN网络就是这些内容,你已经掌握了它,如果你还想和小红传纸条的话,可以试试用它加密,会比移位密码更安全一些。
什么?自己手动代换置换太麻烦?不用怕,贴心的我已经为你准备好了Python代码。
3.3用Python实现SPN网络
我实现的是4轮迭代的SPN网络,以及加密和解密算法,其结构图如下(图片来自CryptographyTheoryandPractice):图5
每次加密输入16比特的明文,输出16比特的密文,代码如下:
#S盒参数
S_Box=[14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7]
#P盒参数
P_Box=[1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]
defgen_K_list(K):
"""
秘钥编排算法,由一个32比特秘钥生成5个16比特子秘钥
:paramK:32比特秘钥
:return:[k1,k2,k3,k4,k5],五个16比特子秘钥
"""
Ks=[]
foriinrange(5,0,-1):
ki=K%(2**16)
Ks.insert(0,ki)
K=K>>4
returnKs
defpi_s(s_box,ur):
"""
分组代换操作
:params_box:S盒参数
:paramur:输入比特串,16比特
:return:输出比特串,16比特
"""
vr=0
foriinrange(4):
uri=ur%(2**4)
vri=s_box[uri]
vr=vr+(vri<<(4*i))
ur=ur>>4
returnvr
defpi_p(p_box,vr):
"""
单比特置换操作
:paramp_box:P盒参数
:paramvr:输入比特串,16比特
:return:输出比特串,16比特
"""
wr=0
foriinrange(15,-1,-1):
vri=vr%2
vr=vr>>1
wr=wr+(vri<<(16-p_box[i]))
returnwr
defreverse_Sbox(s_box):
"""
求S盒的逆
:params_box:S盒参数
:return:S盒的逆
"""
re_box=[-1]*16
foriinrange(16):
re_box[s_box[i]]=i
returnre_box
defreverse_Pbox(p_box):
"""
求P盒的逆
:params_box:P盒参数
:return:P盒的逆
"""
re_box=[-1]*16
foriinrange(16):
re_box[p_box[i]-1]=i+1
returnre_box
defdo_SPN(x,s_box,p_box,Ks):
"""
4轮的SPN网络,可以用来进行加密或解密
:paramx:16比特输入
:params_box:S盒参数
:paramp_box:P盒参数
:paramKs:[k1,k2,k3,k4,k5],五个16比特子秘钥
:return:16比特输出
"""
wr=x
forrinrange(3):
ur=wr^Ks[r]#异或操作
vr=pi_s(s_box,ur)#分组代换
wr=pi_p(p_box,vr)#单比特置换
ur=wr^Ks[3]
vr=pi_s(s_box,ur)
y=vr^Ks[4]
returny
defencrypt(K,x):
"""
根据秘钥K对16比特明文x进行加密
:paramK:32比特秘钥
:paramx:16比特明文
:return:16比特密文
"""
Ks=gen_K_list(K)
returndo_SPN(x,S_Box,P_Box,Ks)
defdecrypt(K,y):
"""
根据秘钥K对16比特密文y进行解密。
:paramK:32比特秘钥
:paramy:16比特密文
:return:16比特明文
"""
Ks=gen_K_list(K)
Ks.reverse()#秘钥逆序编排
#秘钥置换
Ks[1]=pi_p(P_Box,Ks[1])
Ks[2]=pi_p(P_Box,Ks[2])
Ks[3]=pi_p(P_Box,Ks[3])
s_rbox=reverse_Sbox(S_Box)#S盒求逆
p_rbox=reverse_Pbox(P_Box)#P盒求逆
returndo_SPN(y,s_rbox,p_rbox,Ks)
if__name__=='__main__':
x=0b0010011010110111
K=0b00111010100101001101011000111111
print('初始明文:',format(x,'016b'))
print('加密密文:',format(encrypt(K,x),'016b'))
print('解密结果:',format(decrypt(K,encrypt(K,x)),'016b'))
assertdecrypt(K,encrypt(K,x))==x
可以直接看do_SPN函数,函数里面循环3次,对应3轮迭代,第4轮迭代没有置换操作。encrypt与decrypt函数调用do_SPN函数即可进行加密和解密操作(为什么可以调用SPN进行解密?可以对照代码观察SPN的结构想一想),运行程序输出为:
初始明文:0010011010110111
加密密文:1011110011010110
解密结果:0010011010110111
至此,SPN网络已经完全实现!那么它的安全性如何呢?
首先,我们知道,这个SPN网络的秘钥是32位的,大约是有4百万的候选秘钥,这个数量的秘钥,手动穷搜是很难的,用计算机来穷搜就会比较容易了,不过我们随时对它进行改造,增加秘钥长度,如256位,这时候机器穷搜也不行了。
文章分享结束,博客对称排版怎么弄好看和对称加密如何实现的答案你都知道了吗?欢迎再次光临本站哦!