《Python加解密小实验:探索数据加密与解密的世界》
铺垫(1)-源码
import hashlib
source = "你好"
# print(hashlib.md5(source.encode()).hexdigest())# 文件加解密
with open('../文件引用/index.png', 'rb') as file:data = file.read()
# print(hashlib.md5(data).hexdigest())# SHA也是摘要算法
# print(hashlib.sha256(source.encode()).hexdigest())
铺垫(1)-源码解析
这段代码主要演示了如何使用Python的hashlib
库来计算字符串和文件的哈希值
代码解析
-
导入库:
import hashlib
这行代码导入了Python的hashlib
库,该库提供了多种哈希算法,如MD5, SHA1, SHA256等。 2. 字符串哈希:
source = "你好"
# print(hashlib.md5(source.encode()).hexdigest())
这里定义了一个字符串source
,其值为"你好"。接下来的注释代码展示了如何计算该字符串的MD5哈希值。
* `source.encode()`: 将字符串转换为字节串,因为`hashlib`的哈希函数需要字节串作为输入。
* `hashlib.md5(...)`: 创建一个MD5哈希对象。
* `.hexdigest()`: 计算哈希值并返回其十六进制表示。
-
文件哈希:
with open('../文件引用/index.png', 'rb') as file:data = file.read()
# print(hashlib.md5(data).hexdigest())
这部分代码打开了一个名为index.png
的文件,并读取了其内容到变量data
中。接下来的注释代码展示了如何计算该文件内容的MD5哈希值。
* `'rb'`: 以二进制模式打开文件,确保文件内容被正确读取。
-
SHA256哈希:
# SHA也是摘要算法
# print(hashlib.sha256(source.encode()).hexdigest())
这部分代码展示了如何使用SHA256算法计算字符串"你好"的哈希值。与MD5类似,但SHA256提供了更高的安全性。
注意事项
-
哈希算法是单向的,这意味着你不能从哈希值中恢复原始数据。
-
不同的哈希算法有不同的输出长度和安全性。例如,MD5的输出长度为128位,而SHA256的输出长度为256位。
-
哈希算法通常用于验证数据的完整性,而不是加密数据。因为哈希算法是单向的,所以它们不适合用于需要解密数据的场景。
总结
这段代码主要演示了如何使用Python的hashlib
库来计算字符串和文件的哈希值。哈希算法是单向的,主要用于验证数据的完整性。
铺垫(2)-源码
source = 'DSFASsafdasf42343' # dsfasSAFDASF53454
result = ''
for i in source:if ord(i) in range(65, 91):temp = chr(ord(i) + 32)elif ord(i) in range(97, 123):temp = chr(ord(i) - 32)elif ord(i) in range(48, 58):temp = chr(ord(i) + 1)# temp = chr(ord()-1) # 解密算法result += temp
# print(result)
铺垫(2)-源码解析
这段代码的主要目的是对一个字符串source
进行简单的加密处理
-
初始化:
-
source
是一个给定的字符串,其值为 'DSFASsafdasf42343'。 -
result
是一个空字符串,用于存储加密后的结果。
-
-
遍历字符串: 使用
for
循环遍历source
中的每一个字符i
。 -
条件判断与加密:
-
如果字符
i
的ASCII值在65到90之间(即大写字母A-Z),则将其转换为对应的小写字母。这是通过获取字符i
的ASCII值,加32(因为小写字母比对应的大写字母的ASCII值大32),然后再转换回字符来实现的。 -
如果字符
i
的ASCII值在97到122之间(即小写字母a-z),则将其转换为对应的大写字母。这是通过获取字符i
的ASCII值,减32,然后再转换回字符来实现的。 -
如果字符
i
的ASCII值在48到57之间(即数字0-9),则将其转换为下一个数字。例如,'9'会变成':'(这不是一个数字,而是一个冒号字符,因为ASCII值57+1=58,对应的字符是':')。这里有一个注释掉的行# temp = chr(ord()-1) # 解密算法
,这行代码如果取消注释,会将数字减1而不是加1,从而实现解密。
-
-
拼接结果: 将转换后的字符
temp
添加到result
字符串中。 -
输出: 最后,打印加密后的字符串
result
。但需要注意的是,代码中最后一行print(result)
被注释掉了,所以如果直接运行这段代码,不会有任何输出。要看到结果,需要取消这一行的注释。
注意:这段代码并不是一个真正的加密算法,因为它很容易被破解。例如,大写字母总是转换为小写字母,小写字母总是转换为大写字母,数字总是增加1(或减少1)。这种转换模式是固定的,所以很容易通过观察和分析来破解。
如果想要一个真正的加密算法,建议使用像AES、RSA这样的成熟加密算法,这些算法提供了更高的安全性。
铺垫(3)-源码
import stringupper_list = string.ascii_uppercase
lower_list = string.ascii_lowercase# 凯撒加密右移5位
upper_dest = ''
for i in upper_list:index = (upper_list.index(i) + 5) % len(upper_list)print(upper_list[index], end=' ')upper_dest += upper_list[index]
print()
# 凯撒加密右移5位
for i in upper_dest:index = upper_dest.index(i) - 5print(upper_dest[index], end=' ')
铺垫(3)-源码解析
这段代码实现了凯撒加密(Caesar cipher)的一种形式,具体是对英文字母进行右移5位的加密,然后又进行了相应的解密
代码解析
-
导入模块:
import string
导入了Python的string
模块,该模块包含了一些常用的字符串常量,如所有的ASCII字母。 2. 定义字母列表:
upper_list = string.ascii_uppercase
lower_list = string.ascii_lowercase
upper_list
包含了所有的大写英文字母,而lower_list
包含了所有的小写英文字母。 3. 凯撒加密右移5位:
upper_dest = ''
for i in upper_list:index = (upper_list.index(i) + 5) % len(upper_list)print(upper_list[index], end=' ')upper_dest += upper_list[index]
print()
这部分代码实现了对大写字母的凯撒加密右移5位:
* 初始化一个空字符串`upper_dest`来存储加密后的结果。
* 遍历`upper_list`中的每一个字符`i`。
* 使用`upper_list.index(i)`找到字符`i`在`upper_list`中的索引位置,然后加5得到新的索引位置。使用模运算`% len(upper_list)`确保索引不会超出列表的范围。
* 使用新的索引位置从`upper_list`中获取加密后的字符,并打印它(后面跟一个空格)。
* 将加密后的字符添加到`upper_dest`字符串中。
* 最后打印一个换行符。
-
凯撒解密左移5位: 注意:虽然代码注释说是“凯撒加密右移5位”,但这段代码实际上是进行了解密操作,即左移5位。
for i in upper_dest:index = upper_dest.index(i) - 5print(upper_dest[index], end=' ')
这部分代码实现了对加密后的字符串upper_dest
的解密(左移5位):
* 遍历`upper_dest`中的每一个字符`i`。
* 使用`upper_dest.index(i)`找到字符`i`在`upper_dest`中的索引位置,然后减5得到原始字符在`upper_dest`中的索引位置(因为之前加了5位进行加密)。
* 使用这个索引位置从`upper_dest`中获取原始字符,并打印它(后面跟一个空格)。
注意
-
这段代码只处理了大写字母。如果要处理小写字母,你需要对
lower_list
执行类似的操作。 -
凯撒加密是一种简单的替换加密方法,它很容易被破解。因此,在实际应用中,不建议使用凯撒加密来保护敏感信息。
-
在解密部分,代码假设加密是通过右移5位实现的。如果加密是通过其他方式实现的,解密部分可能不会正常工作。
铺垫(4)-源码
list = []
for i in upper:list.append(i)
# print(list)
list2 = ['F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z','A', 'B', 'C', 'D', 'E']
# 凯撒加密,右位移5
for i in list:index = (list.index(i) + 5) % len(list)# print(list[index], end=' ')
# 凯撒解密,左位移5,python特有下标取负数,不需要取余
for i in list2:index = list.index(i) - 5print(list[index], end=' ')
铺垫(4)-源码解析
这段代码实现了凯撒加密(Caesar cipher)的加密和解密过程
代码解析
-
初始化列表:
-
list = []
: 创建一个空列表list
。 -
for i in upper: list.append(i)
: 这段代码似乎是从一个名为upper
的字符串或列表中获取所有字符,并将它们添加到list
中。但请注意,upper
在这段代码中没有定义,可能是在代码的其他部分定义的。 -
list2
: 这是一个包含所有大写字母的列表,但它跳过了'F'到'J'之间的字母,并从'K'开始。这似乎是一个错误,因为通常凯撒加密会处理所有的字母。不过,这段代码可能是为了演示某种特定的移位情况。
-
-
凯撒加密:
-
for i in list: index = (list.index(i) + 5) % len(list)
: 这段代码遍历list
中的每个字符,并计算其在列表中的新位置,新位置是当前位置加5并对列表长度取模。这是凯撒加密的核心思想,即将字母表中的每个字母移动固定的位置数。 -
注:
print(list[index], end=' ')
: 这行代码被注释掉了,如果取消注释,它会打印加密后的字符。
-
-
凯撒解密:
-
for i in list2: index = list.index(i) - 5
: 这段代码遍历list2
中的每个字符,并计算其在list
中的原始位置,原始位置是当前位置减5。这是凯撒解密的核心思想,即将字母表中的每个字母移动回其原始位置。 -
print(list[index], end=' ')
: 这行代码打印解密后的字符。
-
注意事项
-
upper
未定义: 代码中的upper
变量没有在这段代码中定义。它可能是在代码的其他部分定义的,或者这是一个遗漏。 -
list2
的错误:list2
似乎是一个错误的字母表,因为它跳过了'F'到'J'之间的字母。这可能会导致解密过程出现问题。 -
效率问题: 使用
list.index(i)
来查找字符的位置可能不是最高效的方法,特别是当列表很大时。一个更好的方法是使用字典来存储字符和其位置的映射。 -
代码注释: 代码中有一些有用的注释,但也有一些被注释掉的代码。为了更清晰地理解代码,建议删除不必要的注释,并确保所有重要的代码都是可见的。
修改后的代码示例
下面是一个修改后的代码示例,修复了上述提到的一些问题:
# 定义大写字母列表
upper = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'# 初始化加密列表和解密列表
encrypted_list = []
decrypted_list = []# 凯撒加密,右位移5
for char in upper:index = (upper.index(char) + 5) % len(upper)encrypted_char = upper[index]encrypted_list.append(encrypted_char)# 打印加密后的列表
print("Encrypted:", ''.join(encrypted_list))# 凯撒解密,左位移5
for char in encrypted_list:index = (upper.index(char) - 5) % len(upper)decrypted_char = upper[index]decrypted_list.append(decrypted_char)# 打印解密后的列表
print("Decrypted:", ''.join(decrypted_list))
这个修改后的代码更清晰、更完整,并且修复了原始代码中的一些问题。
完整实现-源码
import stringupper_list = string.ascii_uppercase
lower_list = string.ascii_lowercasedef encrypt_zhang(source):# 对大小写字母右移6位dest = ''for i in source:# 如果是大写的情况if i in upper_list:index = (upper_list.index(i) + 6) % len(upper_list)dest += upper_list[index]elif i in lower_list:index = (lower_list.index(i) + 6) % len(lower_list)dest += lower_list[index]return dest# 对字母大小写转换(加解密同源)
def convert_li(source):dest = ''for i in source:if ord(i) in range(65, 91):dest += chr(ord(i) + 32)elif ord(i) in range(97, 123):dest += chr(ord(i) - 32)return dest# 对encrypt_zhang解密,大小写左移6位
def decrypt_zhang(source):dest = ''for i in source:if i in upper_list:index = upper_list.index(i) - 6dest += upper_list[index]elif i in lower_list:index = lower_list.index(i) - 6dest += lower_list[index]return destif __name__ == '__main__':result1 = encrypt_zhang('ZHANGsan')print(result1)result2 = convert_li(result1)print(result2)result3 = decrypt_zhang(result2)print(result3)result4 = convert_li(result3)print(result4)
完整实现-源码解析
这段代码定义了两个加密/解密函数encrypt_zhang
和decrypt_zhang
,以及一个大小写转换函数convert_li
-
导入模块:
import string
导入了Python的string
模块,该模块包含了一些常用的字符串常量和函数。 2. 定义字母列表:
upper_list = string.ascii_uppercase
lower_list = string.ascii_lowercase
upper_list
包含了所有的大写英文字母,而lower_list
包含了所有的小写英文字母。 3. encrypt_zhang函数: 这个函数实现了对输入字符串source
中的每个字母进行右移6位的加密操作。
* 如果字母是大写的,则在`upper_list`中找到其位置,然后加6并取模得到新的位置,从而获取加密后的字母。
* 如果字母是小写的,则在`lower_list`中做类似的操作。
* 其他非字母字符不会被加密。
-
convert_li函数: 这个函数实现了大小写转换的功能。
-
如果字母是大写的(ASCII值在65-90之间),则将其转换为小写。
-
如果字母是小写的(ASCII值在97-122之间),则将其转换为大写。
-
其他非字母字符不会被转换。
-
-
decrypt_zhang函数: 这个函数是
encrypt_zhang
的逆操作,实现了对输入字符串source
中的每个字母进行左移6位的解密操作。其逻辑与encrypt_zhang
相似,只是方向相反。 -
主程序:
-
首先,使用
encrypt_zhang
函数加密字符串'ZHANGsan',并打印结果。 -
然后,使用
convert_li
函数将加密后的字符串的大小写进行转换,并打印结果。 -
接着,使用
decrypt_zhang
函数对上一步得到的字符串进行解密,并打印结果。 -
最后,再次使用
convert_li
函数将解密后的字符串的大小写进行转换,并打印结果。
-
注意:虽然这段代码在逻辑上是正确的,但在实际应用中,这种简单的移位加密方法(如凯撒密码)并不安全,容易被破解。对于需要高安全性的场景,应使用更复杂的加密算法。
另外,这段代码中的encrypt_zhang
和decrypt_zhang
函数只处理了英文字母,对于其他字符(如数字、标点符号等)则不做处理。如果需要处理这些字符,可以在函数中添加相应的逻辑。
相关文章:

《Python加解密小实验:探索数据加密与解密的世界》
铺垫(1)-源码 import hashlib source "你好" # print(hashlib.md5(source.encode()).hexdigest())# 文件加解密 with open(../文件引用/index.png, rb) as file:data file.read() # print(hashlib.md5(data).hexdigest())# SHA也是摘要算法…...

C高级day四shell脚本
1.思维导图 2.终端输入一个C源文件名(.c结尾)判断文件是否有内容,如果没有内容删除文件,如果有内容编译并执行该文件。 #!/bin/bashread -p "请输入一个.c脚本名:" n if [ -s "$n" ] thenecho $n…...

android studio 写一个小计时器(版本二)
as版本:23.3.1patch2 例程:timer 在前一个版本的基本上改的,增加了继续的功能,实现方法稍微不同。 动画演示: activity_main.xml <?xml version"1.0" encoding"utf-8"?> <androidx…...

【网络安全实验室】SQL注入实战详情
如果额头终将刻上皱纹,你只能做到,不让皱纹刻在你的心上 1.最简单的SQL注入 查看源代码,登录名为admin 最简单的SQL注入,登录名写入一个常规的注入语句: 密码随便填,验证码填正确的,点击登录…...

华为,新华三,思科网络设备指令
1. 设备信息查看 华为 display version # 查看设备版本信息 display device # 查看设备硬件信息 新华三(H3C) display version # 查看设备版本信息 display device # 查看设备硬件信息 锐捷 show version …...

WebRTC线程的启动与运行
WebRTC线程运行的基本逻辑: while(true) {…Get(&msg, …);…Dispatch(&msg);… }Dispatch(Message *pmsg) {…pmsg->handler->OnMessage(pmsg);… }在执行函数内部,就是一个while死循环,只做两件事,从队列里Get取…...

Day3 微服务 微服务保护(请求限流、线程隔离、服务熔断)、Sentinel微服务保护框架、分布式事务(XA模式、AT模式)、Seata分布式事务框架
目录 1.微服务保护 1.1.服务保护方案 1.1.1 请求限流 1.1.2 线程隔离 1.1.3 服务熔断 1.2 Sentinel 1.2.1.介绍和安装 1.2.2 微服务整合 1.2.2.1 引入sentinel依赖 1.2.2.2 配置控制台 1.2.2.3 访问cart-service的任意端点 1.3 请求限流 1.4 线程隔离 1.4.1 OpenFeign整合Senti…...

第9章 子程序与函数调用
汇编语言是一种低级编程语言,它几乎是一对一地映射到计算机的机器码指令。在汇编语言中实现循环结构通常涉及到使用条件跳转指令(如 JMP、JE、JNE 等)来控制程序流程。下面我将通过一个简单的例子来讲解如何用x86汇编语言实现一个循环结构。 …...

manacher算法
Manacher 算法快速入门 Manacher 算法是一种用于寻找字符串中最长回文子串的高效算法,时间复杂度为 O(n)。 基本概念 回文 回文是一个字符串,从左到右和从右到左读都一样。 示例: 回文:"aba"、"abba"非回…...

Cocos2dx Lua绑定生成中间文件时参数类型与源码类型不匹配
这两天维护的一个项目,使用arm64-v8a指令集编译时遇到了报错,提示类型不匹配,具体报错的代码【脚本根据C源文件生成的中间文件】如下: const google::protobuf::RepeatedField<unsigned long long>& ret cobj->equi…...

为什么需要 std::call_once?
std::call_once 是 C 标准库中的一个函数,用来确保某个操作仅被执行一次,通常用于线程安全的初始化操作。它常与 std::once_flag 结合使用,后者用于标记某个操作是否已经执行过。 为什么需要 std::call_once? 在多线程程序中&am…...

ubuntu非root用户操作root权限问题-virbox挂在共享文件夹
首先讲一下,virtuallbox 挂在文件夹,操作的时候总是需要root权限,比较费劲。 这一操作其实也正对着我们在Ubuntu上的操作。 前段时间我想在ubuntu正常用户下去操作i2c,也出现了类似的问题。 后来把正常的操作加到组里面也解决了类…...

网络通讯协议
层次协议应用层HTTP, HTTPS, FTP, SMTP, POP3, IMAP, DNS, DHCP, SNMP, Telnet, SSH, SIP, RTP, RTCP, TFTP, NTP, ICMP, IGMP传输层TCP, UDP网络层IP, ICMP, IGMP数据链路层Ethernet, PPP, HDLC, ATM, Frame Relay ISO/OSI 参考模型协议应用层HTTP, HTTPS, FTP, SMTP, POP3, …...

centos,789使用mamba快速安装devtools
如何进入R语言运行环境请参考:Centos7_miniconda_devtools安装_R语言入门之R包的安装_r语言devtools包怎么安装-CSDN博客 在R里面使用安装devtools经常遇到依赖问题,排除过程过于费时,使用conda安装包等待时间长等。下面演示centos,789都是一…...

【人工智能机器学习基础篇】——深入详解强化学习之常用算法Q-Learning与策略梯度,掌握智能体与环境的交互机制
深入详解强化学习之常用算法:Q-Learning与策略梯度 强化学习(Reinforcement Learning, RL)作为机器学习的一个重要分支,近年来在多个领域取得了显著成果。从棋类游戏的人机对战到自主驾驶汽车,强化学习技术展示了其强大…...

银河麒麟桌面v10sp1修复引导笔记
1.安装双系统最好备份esp分区,uefi引导丢失可以用diskgen,选择工具再点击设置uefi bios,鼠标右键选择efi文件。 2.银河麒麟界面添加windows,复制EFI/Microsoft或者pe生成引导文件后,修复Windows引导用下面命令 /桌面# update-gru…...

深入理解 MVCC 与 BufferPool 缓存机制
深入理解 MVCC 与 BufferPool 缓存机制 在 MySQL 数据库中,MVCC(Multi-Version Concurrency Control)多版本并发控制机制和 BufferPool 缓存机制是非常重要的概念,它们对于保证数据的一致性、并发性以及提升数据库性能起着关键作用…...

vue实现下拉多选、可搜索、全选功能
最后的效果就是树形的下拉多选,可选择任意一级选项,下拉框中有一个按钮可以实现全选,也支持搜索功能。 在mounted生命周期里面获取全部部门的数据,handleTree是讲接口返回的数据整理成树形结构,可以自行解决 <div c…...

探秘Kafka源码:关键内容解析
文章目录 一、以kafka-3.0.0为例1.1安装 gradle 二、生产者源码2.1源码主流程图2.2 初始化2.3生产者sender线程初始化2.4 程序入口2.5生产者 main 线程初始化2.6 跳转到 KafkaProducer构造方法 一、以kafka-3.0.0为例 打开 IDEA,点击 File->Open…->源码包解…...

Android音频效果处理:基于`android.media.audiofx`包的原理、架构与实现
Android音频效果处理:基于android.media.audiofx包的原理、架构与实现 目录 引言Android音频框架概述android.media.audiofx包简介音频效果处理的原理 4.1 音频信号处理基础4.2 常见音频效果android.media.audiofx的架构设计 5.1 类结构分析5.2 设计模式应用系统定制与扩展 6…...

LeetCode - 初级算法 数组(两个数组的交集 II)
两个数组的交集 II 这篇文章讨论如何求两个数组的交集,并返回结果中每个元素出现的次数与其在两个数组中都出现的次数一致。提供多个实现方法以满足不同场景需求。 免责声明:本文来源于个人知识与公开资料,仅用于学术交流。 描述 给定两个整数数组 nums1 和 nums2,以数…...

SQL 实战:分页查询的多种方式对比与优化
在处理大数据表时,分页查询是非常常见的需求。分页不仅可以提高用户体验,还能有效减少数据库查询返回的数据量,避免一次性加载大量记录引起的性能瓶颈。 然而,在数据量较大或复杂查询中,简单的分页方式可能导致性能下降…...
汇川Easy系列正弦信号发生器(ST源代码)
正弦余弦信号发生器CODESYS和MATLAB实现请参考下面文章链接: 正弦余弦信号发生器应用(CODESYS ST源代码+MATLAB仿真)_st语言根据输入值,形成正弦点-CSDN博客文章浏览阅读410次。本文介绍了如何在CODESYS编程环境中创建正弦和余弦信号发生器。通过详细的PLC梯形图和SCL语言代码…...

JavaSpring AI与阿里云通义大模型的集成使用Java Data Science Library(JDSL)进行数据处理
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默, 忍不住分享一下给大家。点击跳转到网站 学习总结 1、掌握 JAVA入门到进阶知识(持续写作中……) 2、学会Oracle数据库入门到入土用法(创作中……) 3、手把…...

Three.js教程002:Three.js结合Vue进行开发
文章目录 Three.js结合Vue开发创建Vue项目安装依赖运行项目安装three使用three.js完整代码下载Three.js结合Vue开发 创建Vue项目 创建命令: npm init vite@latest框架这里选择【Vue】: 安装依赖 安装命令: cd 01-vueapp npm install运行项目 npm run dev...

pycharm+anaconda创建项目
pycharmanaconda创建项目 安装: Windows下PythonPyCharm的安装步骤及PyCharm的使用-CSDN博客 详细Anaconda安装配置环境创建教程-CSDN博客 创建项目: 开始尝试新建一个项目吧! 选择好项目建设的文件夹 我的项目命名为:pyth…...

vue2中遇到的问题与解决方案(自用)
1 、在vue2中怎么能成功渲染字符串中存在自定义组件 比如,前端样式定义后由接口返回想渲染的样式,如果此时直接使用v-html,那么vue的自定义组件或者ui框架的组件是会被直接引用不能编译成功 解决方案: 此时想到vue官网使用render函…...
CF2043b-B. Digits
题目链接 题意:给定两个整数n、d,要求找出排列成n!个d之后的数可以被1-9中奇数整除的数 题解: 主要是考察分类讨论: 被3整除,当d能被3整除时一定成立或者n > 3,当n > 3时n!一定包含因数3 被5整除&a…...

ultralytics库RT-DETR代码解析
最近读了maskformer以及maskdino的分割头设计,于是想在RT-DETR上做一个分割的改动,所以选择在ultralytics库中对RTDETR进行改进。 本文内容简介: 1.ultralytics库中RT-DETR模型解析 2. 对ultralytics库中的RT-DETR模型增加分割头做实例分割 1.ultralytics库中RT-DETR模型解…...

(七)- plane/crtc/encoder/connector objects
1,framebuffer/plane Rockchip RK3399 - DRM framebuffer、plane基础知识 - 大奥特曼打小怪兽 - 博客园 2,crtc Rockchip RK3399 - DRM crtc基础知识 - 大奥特曼打小怪兽 - 博客园 3,encoder/connector/bridge Rockchip RK3399 - DRM en…...