<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://ocr.michiyo.me/w/index.php?action=history&amp;feed=atom&amp;title=Component%2Fdata%2Fzh</id>
	<title>Component/data/zh - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://ocr.michiyo.me/w/index.php?action=history&amp;feed=atom&amp;title=Component%2Fdata%2Fzh"/>
	<link rel="alternate" type="text/html" href="https://ocr.michiyo.me/w/index.php?title=Component/data/zh&amp;action=history"/>
	<updated>2026-08-24T15:14:56Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.9</generator>
	<entry>
		<id>https://ocr.michiyo.me/w/index.php?title=Component/data/zh&amp;diff=1147&amp;oldid=prev</id>
		<title>imported&gt;OCDoc Import: Imported from legacy OpenComputers documentation at ocdoc.cil.li</title>
		<link rel="alternate" type="text/html" href="https://ocr.michiyo.me/w/index.php?title=Component/data/zh&amp;diff=1147&amp;oldid=prev"/>
		<updated>2026-08-24T08:08:27Z</updated>

		<summary type="html">&lt;p&gt;Imported from legacy OpenComputers documentation at ocdoc.cil.li&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;= 组件：数据卡 =&lt;br /&gt;
&lt;br /&gt;
此组件由[[Item/data card/zh|数据卡]]提供。&lt;br /&gt;
&lt;br /&gt;
组件名：`data`。&lt;br /&gt;
&lt;br /&gt;
== 1级回调函数 ==&lt;br /&gt;
&lt;br /&gt;
* `crc32(data:string):string`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;计算数据的CRC-32哈希值。结果为二进制格式。  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* `decode64(data:string):string`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;对数据进行base64解码。  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* `encode64(data:string):string`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;对数据进行base64编码。结果为二进制格式。  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* `md5(data:string):string`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;计算数据的MD5哈希值。结果为二进制格式。  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* `sha256(data:string):string`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;计算数据的SHA2-256哈希值。结果为二进制格式。  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* `deflate(data:string):string`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;将数据用deflate算法压缩。  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* `inflate(data:string):string`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;将数据用infalte算法解压。  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* `getLimit():number`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;返回单次最大可传递给此扩展卡其他函数多少数据。&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== 2级回调函数 ==&lt;br /&gt;
&lt;br /&gt;
* `encrypt(data:string, key:string, iv:string):string`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;使用给定密钥以及初始向量IV（最好为随机）对数据进行AES加密。  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* `decrypt(data:string, key:string, iv:string):string`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;使用给定密钥以及初始向量IV对数据进行AES解密。  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* `random(len:number):string`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;生成长度为 `len` 的随机二进制字符串。&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== 3级回调函数 ==&lt;br /&gt;
&lt;br /&gt;
* `generateKeyPair([bitLen:number]):table, table`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;生成一对可用于多种加密算法的公钥与私钥。可选的第二个参数代表密钥长度，值可为256或384。  &lt;br /&gt;
密钥类型包括&amp;quot;ec-public&amp;quot;和&amp;quot;ec-private&amp;quot;。密钥可以使用`key.serialize():string`来序列化。密钥中还包含一个函数`key.isPublic():boolean`。  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* `ecdsa(data:string, key:userdata[, sig:string]):string or boolean`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;不给定签名则使用给定私钥生成数据的一份签名。若给定了签名则功能为使用公钥、先前生成的签名字符串以及原字符串校验签名。  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* `ecdh(privateKey:userdata, publicKey:userdata):string`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;使用第一个参数给出的用户私钥与第二个参数给出的用户公钥，生成一个Diffie-Hellman共享密钥。密钥基本关系的示例为：  &lt;br /&gt;
`ecdh(userA.private, userB.public) == ecdh(userB.private, userA.public)`  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* `deserializeKey(data:string, type:string):table`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;将密钥从字符串形式转化为其特有形式。&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== 样例 ==&lt;br /&gt;
&lt;br /&gt;
此扩展卡可用于向其他在游戏中或在现实中的人发送加密数据。既然我们有能力创建密钥对和Diffie-Hellman共享密钥，那么我们就可以与这些人建立加密连接。&lt;br /&gt;
&lt;br /&gt;
使用密钥对进行加密时，基本步骤为：&lt;br /&gt;
&lt;br /&gt;
预备工作：&lt;br /&gt;
&lt;br /&gt;
* （下列工作需要&amp;#039;&amp;#039;&amp;#039;接收者&amp;#039;&amp;#039;&amp;#039;完成）&lt;br /&gt;
* 生成一个公钥（`rPublic`）与一个私钥（`rPrivate`）。&lt;br /&gt;
&amp;#039;&amp;#039; \&amp;#039;&amp;#039;\*若不能进行自动密钥交换，则你需要将`rPublic`手动传给&amp;#039;&amp;#039;&amp;#039;发送者&amp;#039;&amp;#039;&amp;#039;。&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;发送者&amp;#039;&amp;#039;&amp;#039;必须：&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039; \&amp;#039;&amp;#039;\&amp;#039;&amp;#039;\&amp;#039;&amp;#039;读取&amp;#039;&amp;#039;&amp;#039;接收者&amp;#039;&amp;#039;&amp;#039;的公钥（`rPublic`），将其解序列化并重构出密钥对象。&lt;br /&gt;
* 生成一个公钥（`sPublic`）和一个私钥（`sPrivate`）。&lt;br /&gt;
&amp;#039;&amp;#039; \&amp;#039;&amp;#039;用`rPublic`和`sPrivate`生成加密密钥。&lt;br /&gt;
* 生成一个初始向量（IV）。&lt;br /&gt;
* 使用`sPublic.serialize()`将`sPublic`转化为字符串&lt;br /&gt;
&amp;#039;&amp;#039; &amp;#039;&amp;#039;\&amp;#039;&amp;#039;\&amp;#039;&amp;#039;用serialization(序列化)库将数据序列化，然后使用加密密钥和IV将其加密。&lt;br /&gt;
* 序列化并发送信息，其中有明文形式的`sPublic`与IV。&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;接收者&amp;#039;&amp;#039;&amp;#039;必须：&lt;br /&gt;
&lt;br /&gt;
* 读取&amp;#039;&amp;#039;&amp;#039;发送者&amp;#039;&amp;#039;&amp;#039;的私钥（`rPrivate`），将其解序列化并重构出密钥对象。&lt;br /&gt;
* 接收信息，并使用serialization(序列化)运行库将其解序列化。然后使用`data.deserializeKey()`解序列化`sPublic`。&lt;br /&gt;
&amp;#039;&amp;#039; \&amp;#039;&amp;#039;使用`sPublic`和`rPrivate`生成解密密钥。&lt;br /&gt;
* 使用解密密钥和IV来解密信息。&lt;br /&gt;
* 解序列化解密后的信息。&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;注\*：&amp;#039;&amp;#039;&amp;#039;上文中使用了“加密密钥”和“解密密钥”两个术语。这两个密钥完全相同，因为这两个密钥都是使用`ecdh()`函数生成的。&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;注\&amp;#039;&amp;#039;\&amp;#039;&amp;#039;：&amp;#039;&amp;#039;&amp;#039;上文说“你需要将`rPublic`手动传给&amp;#039;&amp;#039;&amp;#039;发送者&amp;#039;&amp;#039;&amp;#039;”。但是在使用握手协议的系统中情况并非如此。例如，&amp;#039;&amp;#039;&amp;#039;发送者&amp;#039;&amp;#039;&amp;#039;会让&amp;#039;&amp;#039;&amp;#039;接收者&amp;#039;&amp;#039;&amp;#039;知道自己的存在，然后&amp;#039;&amp;#039;&amp;#039;接收者&amp;#039;&amp;#039;&amp;#039;会回复给&amp;#039;&amp;#039;&amp;#039;发送者&amp;#039;&amp;#039;&amp;#039;一个公钥（可能还有附加信息，例如密钥长度）。为简单起见，以下示例不涵盖握手协议的功能。&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;注\&amp;#039;&amp;#039;\&amp;#039;&amp;#039;\*：&amp;#039;&amp;#039;&amp;#039;上文与下文的示例提到需要将密钥和信息序列化/解序列化。总体来说，在你将数据（尤其是二进制形式的）写入文件或通过网络传输前对其序列化是有益的。序列化能保证二进制数据“有结尾”，使你的脚本或shell读取时更加安全。&lt;br /&gt;
&lt;br /&gt;
若要发送加密数据： ```lua local serialization = require(&amp;quot;serialization&amp;quot;) local component = require(&amp;quot;component&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
--此表包含了要发送到接收方电脑的数据。 --表中还有信息头，供接收方用来解密数据。 local __packet = {&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  header =&lt;br /&gt;
  {&lt;br /&gt;
      sPublic    = nil,&lt;br /&gt;
      iv         = nil&lt;br /&gt;
  },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;  data = nil&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
--读取公钥文件。 local file = io.open(&amp;quot;rPublic&amp;quot;,&amp;quot;rb&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
local rPublic = file:read(&amp;quot;*a&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
file:close()&lt;br /&gt;
&lt;br /&gt;
--将公钥解序列化为二进制形式。 local rPublic = serialization.unserialize(rPublic)&lt;br /&gt;
&lt;br /&gt;
--重建公钥对象。 local rPublic = component.data.deserializeKey(rPublic,&amp;quot;ec-public&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
--为此会话生成一个公钥与一个私钥。 local sPublic, sPrivate = component.data.generateKeyPair(384)&lt;br /&gt;
&lt;br /&gt;
--生成一个加密密钥。 local encryptionKey = component.data.md5(component.data.ecdh(sPrivate, rPublic))&lt;br /&gt;
&lt;br /&gt;
--将信息头中值&amp;#039;iv&amp;#039;设定为一个随机生成的16位数字字符串。 __packet.header.iv = component.data.random(16)&lt;br /&gt;
&lt;br /&gt;
--将信息头中值&amp;#039;sPublic&amp;#039;设定为一个字符串。 __packet.header.sPublic = sPublic.serialize()&lt;br /&gt;
&lt;br /&gt;
--待加密的数据。 __packet.data = &amp;quot;lorem ipsum&amp;quot;&lt;br /&gt;
&lt;br /&gt;
--数据被序列化并被加密了。 &amp;lt;span class=&amp;quot;underline&amp;quot;&amp;gt;packet.data = component.data.encrypt(serialization.serialize(&amp;lt;/span&amp;gt;packet.data), encryptionKey, __packet.header.iv)&lt;br /&gt;
&lt;br /&gt;
--为简单起见，此样例中的电脑使用连接卡（ocdoc.cil.li/item:linked_card:zh） component.tunnel.send(serialization.serialize(__packet)) ``` 若要接收加密数据： ```lua local serialization = require(&amp;quot;serialization&amp;quot;) local component = require(&amp;quot;component&amp;quot;) local event = require(&amp;quot;event&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
--读取私钥。 local file = io.open(&amp;quot;rPrivate&amp;quot;,&amp;quot;rb&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
local rPrivate = file:read(&amp;quot;*a&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
file:close()&lt;br /&gt;
&lt;br /&gt;
--将私钥解序列化。 local rPrivate = serialization.unserialize(rPrivate)&lt;br /&gt;
&lt;br /&gt;
--重建私钥对象。 local rPrivate = component.data.deserializeKey(rPrivate,&amp;quot;ec-private&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
--使用event.pull()以接收来自发送者的信息。 local _, _, _, _, _, message = event.pull(&amp;quot;modem_message&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
--将信息解序列化。 local message = serialization.unserialize(message)&lt;br /&gt;
&lt;br /&gt;
--从信息中获取公钥并解序列化。 local sPublic = component.data.deserializeKey(message.header.sPublic,&amp;quot;ec-public&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
--生成解密密钥。 local decryptionKey = component.data.md5(component.data.ecdh(rPrivate, sPublic))&lt;br /&gt;
&lt;br /&gt;
--使用解密密钥和IV来解密message.data中的加密数据 local data = component.data.decrypt(message.data, decryptionKey, message.header.iv)&lt;br /&gt;
&lt;br /&gt;
--解序列化解密后的数据。 local data = serialization.unserialize(data)&lt;br /&gt;
&lt;br /&gt;
--输出解密后的数据。 print(data) ```&lt;br /&gt;
&lt;br /&gt;
== 目录 ==&lt;br /&gt;
&lt;br /&gt;
{{:Component/contents/zh}}&lt;br /&gt;
&lt;/div&gt;</summary>
		<author><name>imported&gt;OCDoc Import</name></author>
	</entry>
</feed>