【文件格式探究】EP.1 对ePub文件格式的初探

这是“文件格式探究”专题的第 1 期——初探 “ePub” 文件格式。这个专题将会给各位读者呈现笔者探索各种文件格式的过程,具体则是文件的内容是如何呈现出来的。原则上我们假定仅对于这些文件格式的用途有所了解,但具体实现的细节并不清楚 (如果提前掌握了部分内容,笔者全当其不存在) 。探究过程中我们会尝试使用各种方法来逐渐初步掌握其概貌。

文件格式简介

根据维基百科大陆简体版本的相关描述:

EPub 是一个自由的开放标准,属于一种可以“自动重新排版”的内容;也就是文字内容可以根据阅读设备的特性,以最适于阅读的方式显示。

之所以后面不截是因为再截就剧透了。简单来说,ePub 就是类似于 PDF 那样的“文档型”文件格式,常用于分发电子读物等。

探究过程

环境

现在笔者手头上有一份用于测试的 ePub 文件,文件路径为 ~/Downloads/咖啡馆推理事件簿系列(全四本).epub (趁机夹带私货,反正很合我胃口就是了) ,后续所有的探究活动均建立于此文件上。笔者目前的操作系统环境为 Manjaro 21.1.0 on amd64,终端环境为 GNU bash 5.1.8(1)-release 。为了方便,我们先把文件改个名字 (那你还把原来的名字给出来干嘛?!) :

[littleye233@lymjrolt Downloads]$ cd ~
[littleye233@lymjrolt ~]$ cd Downloads
[littleye233@lymjrolt Downloads]$ mv 咖啡馆推理事件簿系列(全四本).epub test.epub
[littleye233@lymjrolt Downloads]$ ll test.epub
-rw-r--r-- 1 littleye233 littleye233 1253964 Aug 22 23:24 test.epub

Round I. 文件类型

首先我们先尝试用 Linux 系统的内置命令 file 试试水,看看会输出什么东西。键入 file test.epub后执行:

[littleye233@lymjrolt Downloads]$ file test.epub
test.epub: EPUB document EPUB document

哎呀,真可惜! file 命令几乎什么有效信息都没给我们。 file 命令的 man 页面明确给出此命令可以判断文件格式,但其实它能做到的有很多,例如如果对一个图片文件使用 file ,可能会出现类似下面的结果:

[littleye233@lymjrolt Downloads]$ file ~/.local/share/osu/screenshots/osu_2021-08-21_23-40-03.png
/home/littleye233/.local/share/osu/screenshots/osu_2021-08-21_23-40-03.png: PNG image data, 1920 x 961, 8-bit/color RGBA, non-interlaced

这样我们可以通过 file 中提供的相关信息顺藤摸瓜,尝试在文件的二进制编码内容中寻找其蛛丝马迹,进而推测对应“位点”所表达的含义 (因为一些文件格式要求在特定的位置表达某些含义) ,如果能提供类似注释的信息就再好不过了。

Round II. 文件结构

现在我们回到这个 ePub 文件上来。现在我们尝试能否直接获取其内容,目的是通过文件头部的部分可见字符猜测其文件结构。输入 nano test.epub 直接预览,或使用 head --bytes=120 test.epub 查看前面 120 个字节的内容:

[littleye233@lymjrolt Downloads]$ head --bytes=120 test.epub
PK!oa�mimetypeapplication/epub+zipPU�N�;�ʯ�META-INF/container.xml]�A
�0E�=

果不其然,我们看到了一些有趣的字眼: “mimetypeapplication/epub+zip” ,凭经验猜测,这应该是 ePub 文件格式的文件头,而其中的 “zip” 也说明—— ePub 文件可能本质上就是一个压缩档。

其实很多文件格式 (例如 Word 文档 “*.docx”) 其本质都是在一个压缩档中加入各种资源文件和配置文件,只要有对应的软件进行读取并重新加工,用户即能看到效果。

Round III. 目录树结构

现在我们可以使用解压缩程序解出 ePub 文件中的内容了。在终端中执行 unzip -l test.epub

[littleye233@lymjrolt Downloads]$ unzip -l test.epub
Archive:  test.epub
  Length      Date    Time    Name
---------  ---------- -----   ----
       20  1980-01-01 00:00   mimetype
      251  2019-06-27 10:40   META-INF/container.xml
    12307  2019-06-27 10:40   OEBPS/content.opf
   112368  2019-06-27 10:40   OEBPS/Images/cover00464.jpeg
   128680  2019-06-27 10:40   OEBPS/Images/image00456.jpeg
   120936  2019-06-27 10:40   OEBPS/Images/image00457.jpeg
     1392  2019-06-27 10:40   OEBPS/Images/image00458.jpeg
   101948  2019-06-27 10:40   OEBPS/Images/image00459.jpeg
   119124  2019-06-27 10:40   OEBPS/Images/image00460.jpeg
     1268  2019-06-27 10:40   OEBPS/Images/image00461.jpeg
    42944  2019-06-27 10:40   OEBPS/Images/image00462.jpeg
   121284  2019-06-27 10:40   OEBPS/Images/image00463.jpeg
     2251  2019-06-27 10:40   OEBPS/Styles/style0001.css
     9816  2019-06-27 10:40   OEBPS/Styles/style0002.css
     2251  2019-06-27 10:40   OEBPS/Styles/style0003.css
     9789  2019-06-27 10:40   OEBPS/Styles/style0004.css
     2251  2019-06-27 10:40   OEBPS/Styles/style0005.css
    29245  2019-06-27 10:40   OEBPS/Styles/style0006.css
     2235  2019-06-27 10:40   OEBPS/Styles/style0007.css
    29914  2019-06-27 10:40   OEBPS/Styles/style0008.css
     2251  2019-06-27 10:40   OEBPS/Styles/style0009.css
      624  2019-06-27 10:40   OEBPS/Text/cover_page.xhtml
      851  2019-06-27 10:40   OEBPS/Text/part0000.xhtml
      561  2019-06-27 10:40   OEBPS/Text/part0001.xhtml
      428  2019-06-27 10:40   OEBPS/Text/part0002.xhtml
     1518  2019-06-27 10:40   OEBPS/Text/part0003.xhtml
      661  2019-06-27 10:40   OEBPS/Text/part0004.xhtml
     2311  2019-06-27 10:40   OEBPS/Text/part0005.xhtml
    55157  2019-06-27 10:40   OEBPS/Text/part0006.xhtml
    58266  2019-06-27 10:40   OEBPS/Text/part0007.xhtml
    59953  2019-06-27 10:40   OEBPS/Text/part0008.xhtml
    49789  2019-06-27 10:40   OEBPS/Text/part0009.xhtml
    66870  2019-06-27 10:40   OEBPS/Text/part0010.xhtml
    57342  2019-06-27 10:40   OEBPS/Text/part0011.xhtml
    67449  2019-06-27 10:40   OEBPS/Text/part0012.xhtml
    16183  2019-06-27 10:40   OEBPS/Text/part0013.xhtml
      561  2019-06-27 10:40   OEBPS/Text/part0014.xhtml
      428  2019-06-27 10:40   OEBPS/Text/part0015.xhtml
     1575  2019-06-27 10:40   OEBPS/Text/part0016.xhtml
      496  2019-06-27 10:40   OEBPS/Text/part0017.xhtml
     1446  2019-06-27 10:40   OEBPS/Text/part0018.xhtml
    52358  2019-06-27 10:40   OEBPS/Text/part0019.xhtml
    75746  2019-06-27 10:40   OEBPS/Text/part0020.xhtml
    63420  2019-06-27 10:40   OEBPS/Text/part0021.xhtml
    57399  2019-06-27 10:40   OEBPS/Text/part0022.xhtml
    58590  2019-06-27 10:40   OEBPS/Text/part0023.xhtml
    40263  2019-06-27 10:40   OEBPS/Text/part0024.xhtml
    66099  2019-06-27 10:40   OEBPS/Text/part0025.xhtml
    15143  2019-06-27 10:40   OEBPS/Text/part0026.xhtml
      561  2019-06-27 10:40   OEBPS/Text/part0027.xhtml
      612  2019-06-27 10:40   OEBPS/Text/part0028.xhtml
     1344  2019-06-27 10:40   OEBPS/Text/part0029.xhtml
      640  2019-06-27 10:40   OEBPS/Text/part0030.xhtml
     6144  2019-06-27 10:40   OEBPS/Text/part0031.xhtml
    25197  2019-06-27 10:40   OEBPS/Text/part0032.xhtml
    54594  2019-06-27 10:40   OEBPS/Text/part0033.xhtml
    87394  2019-06-27 10:40   OEBPS/Text/part0034.xhtml
    97557  2019-06-27 10:40   OEBPS/Text/part0035.xhtml
   109901  2019-06-27 10:40   OEBPS/Text/part0036.xhtml
    17181  2019-06-27 10:40   OEBPS/Text/part0037.xhtml
     5238  2019-06-27 10:40   OEBPS/Text/part0038.xhtml
      561  2019-06-27 10:40   OEBPS/Text/part0039.xhtml
      644  2019-06-27 10:40   OEBPS/Text/part0040.xhtml
     1163  2019-06-27 10:40   OEBPS/Text/part0041.xhtml
     1473  2019-06-27 10:40   OEBPS/Text/part0042.xhtml
    38427  2019-06-27 10:40   OEBPS/Text/part0043.xhtml
    90589  2019-06-27 10:40   OEBPS/Text/part0044.xhtml
    51278  2019-06-27 10:40   OEBPS/Text/part0045.xhtml
    58321  2019-06-27 10:40   OEBPS/Text/part0046.xhtml
    29670  2019-06-27 10:40   OEBPS/Text/part0047.xhtml
    12903  2019-06-27 10:40   OEBPS/Text/part0048.xhtml
     7364  2019-06-27 10:40   OEBPS/toc.ncx
---------                     -------
  2422768                     72 files

同时可以直接解压:

[littleye233@lymjrolt Downloads]$ unzip test.epub -d test_epub
Archive:  test.epub
 extracting: test_epub/mimetype
  inflating: test_epub/META-INF/container.xml
  inflating: test_epub/OEBPS/content.opf
  inflating: test_epub/OEBPS/Images/cover00464.jpeg
  inflating: test_epub/OEBPS/Images/image00456.jpeg
  inflating: test_epub/OEBPS/Images/image00457.jpeg
  inflating: test_epub/OEBPS/Images/image00458.jpeg
  inflating: test_epub/OEBPS/Images/image00459.jpeg
  inflating: test_epub/OEBPS/Images/image00460.jpeg
  inflating: test_epub/OEBPS/Images/image00461.jpeg
  inflating: test_epub/OEBPS/Images/image00462.jpeg
  inflating: test_epub/OEBPS/Images/image00463.jpeg
  inflating: test_epub/OEBPS/Styles/style0001.css
  inflating: test_epub/OEBPS/Styles/style0002.css
  inflating: test_epub/OEBPS/Styles/style0003.css
  inflating: test_epub/OEBPS/Styles/style0004.css
  inflating: test_epub/OEBPS/Styles/style0005.css
  inflating: test_epub/OEBPS/Styles/style0006.css
  inflating: test_epub/OEBPS/Styles/style0007.css
  inflating: test_epub/OEBPS/Styles/style0008.css
  inflating: test_epub/OEBPS/Styles/style0009.css
  inflating: test_epub/OEBPS/Text/cover_page.xhtml
  inflating: test_epub/OEBPS/Text/part0000.xhtml
  inflating: test_epub/OEBPS/Text/part0001.xhtml
  inflating: test_epub/OEBPS/Text/part0002.xhtml
  inflating: test_epub/OEBPS/Text/part0003.xhtml
  inflating: test_epub/OEBPS/Text/part0004.xhtml
  inflating: test_epub/OEBPS/Text/part0005.xhtml
  inflating: test_epub/OEBPS/Text/part0006.xhtml
  inflating: test_epub/OEBPS/Text/part0007.xhtml
  inflating: test_epub/OEBPS/Text/part0008.xhtml
  inflating: test_epub/OEBPS/Text/part0009.xhtml
  inflating: test_epub/OEBPS/Text/part0010.xhtml
  inflating: test_epub/OEBPS/Text/part0011.xhtml
  inflating: test_epub/OEBPS/Text/part0012.xhtml
  inflating: test_epub/OEBPS/Text/part0013.xhtml
  inflating: test_epub/OEBPS/Text/part0014.xhtml
  inflating: test_epub/OEBPS/Text/part0015.xhtml
  inflating: test_epub/OEBPS/Text/part0016.xhtml
  inflating: test_epub/OEBPS/Text/part0017.xhtml
  inflating: test_epub/OEBPS/Text/part0018.xhtml
  inflating: test_epub/OEBPS/Text/part0019.xhtml
  inflating: test_epub/OEBPS/Text/part0020.xhtml
  inflating: test_epub/OEBPS/Text/part0021.xhtml
  inflating: test_epub/OEBPS/Text/part0022.xhtml
  inflating: test_epub/OEBPS/Text/part0023.xhtml
  inflating: test_epub/OEBPS/Text/part0024.xhtml
  inflating: test_epub/OEBPS/Text/part0025.xhtml
  inflating: test_epub/OEBPS/Text/part0026.xhtml
  inflating: test_epub/OEBPS/Text/part0027.xhtml
  inflating: test_epub/OEBPS/Text/part0028.xhtml
  inflating: test_epub/OEBPS/Text/part0029.xhtml
  inflating: test_epub/OEBPS/Text/part0030.xhtml
  inflating: test_epub/OEBPS/Text/part0031.xhtml
  inflating: test_epub/OEBPS/Text/part0032.xhtml
  inflating: test_epub/OEBPS/Text/part0033.xhtml
  inflating: test_epub/OEBPS/Text/part0034.xhtml
  inflating: test_epub/OEBPS/Text/part0035.xhtml
  inflating: test_epub/OEBPS/Text/part0036.xhtml
  inflating: test_epub/OEBPS/Text/part0037.xhtml
  inflating: test_epub/OEBPS/Text/part0038.xhtml
  inflating: test_epub/OEBPS/Text/part0039.xhtml
  inflating: test_epub/OEBPS/Text/part0040.xhtml
  inflating: test_epub/OEBPS/Text/part0041.xhtml
  inflating: test_epub/OEBPS/Text/part0042.xhtml
  inflating: test_epub/OEBPS/Text/part0043.xhtml
  inflating: test_epub/OEBPS/Text/part0044.xhtml
  inflating: test_epub/OEBPS/Text/part0045.xhtml
  inflating: test_epub/OEBPS/Text/part0046.xhtml
  inflating: test_epub/OEBPS/Text/part0047.xhtml
  inflating: test_epub/OEBPS/Text/part0048.xhtml
  inflating: test_epub/OEBPS/toc.ncx

为了更清楚地显示文件树结构,我们也可以使用 tree 命令 (这个命令在 Windows 中是内置的,在 Linux 中需要安装 tree 这个包,使用软件包管理器或编译安装均可) :

[littleye233@lymjrolt test_epub]$ tree
.
├── META-INF
│   └── container.xml
├── mimetype
└── OEBPS
    ├── content.opf
    ├── Images
    │   ├── cover00464.jpeg
    │   ├── image00456.jpeg
    │   ├── image00457.jpeg
    │   ├── image00458.jpeg
    │   ├── image00459.jpeg
    │   ├── image00460.jpeg
    │   ├── image00461.jpeg
    │   ├── image00462.jpeg
    │   └── image00463.jpeg
    ├── Styles
    │   ├── style0001.css
    │   ├── style0002.css
    │   ├── style0003.css
    │   ├── style0004.css
    │   ├── style0005.css
    │   ├── style0006.css
    │   ├── style0007.css
    │   ├── style0008.css
    │   └── style0009.css
    ├── Text
    │   ├── cover_page.xhtml
    │   ├── part0000.xhtml
    │   ├── part0001.xhtml
    │   ├── part0002.xhtml
    │   ├── part0003.xhtml
    │   ├── part0004.xhtml
    │   ├── part0005.xhtml
    │   ├── part0006.xhtml
    │   ├── part0007.xhtml
    │   ├── part0008.xhtml
    │   ├── part0009.xhtml
    │   ├── part0010.xhtml
    │   ├── part0011.xhtml
    │   ├── part0012.xhtml
    │   ├── part0013.xhtml
    │   ├── part0014.xhtml
    │   ├── part0015.xhtml
    │   ├── part0016.xhtml
    │   ├── part0017.xhtml
    │   ├── part0018.xhtml
    │   ├── part0019.xhtml
    │   ├── part0020.xhtml
    │   ├── part0021.xhtml
    │   ├── part0022.xhtml
    │   ├── part0023.xhtml
    │   ├── part0024.xhtml
    │   ├── part0025.xhtml
    │   ├── part0026.xhtml
    │   ├── part0027.xhtml
    │   ├── part0028.xhtml
    │   ├── part0029.xhtml
    │   ├── part0030.xhtml
    │   ├── part0031.xhtml
    │   ├── part0032.xhtml
    │   ├── part0033.xhtml
    │   ├── part0034.xhtml
    │   ├── part0035.xhtml
    │   ├── part0036.xhtml
    │   ├── part0037.xhtml
    │   ├── part0038.xhtml
    │   ├── part0039.xhtml
    │   ├── part0040.xhtml
    │   ├── part0041.xhtml
    │   ├── part0042.xhtml
    │   ├── part0043.xhtml
    │   ├── part0044.xhtml
    │   ├── part0045.xhtml
    │   ├── part0046.xhtml
    │   ├── part0047.xhtml
    │   └── part0048.xhtml
    └── toc.ncx

5 directories, 72 files

Round IV. 内部文件

到这里我们大概就能猜出来:

  • META-INF 文件夹:里面存放的应该是“容器” (也就是这个 ePub 文件) 的相关配置文件;
  • mimetype 文件:里面定义了这个文件的类型为 “ePub” (其中 “MIME” 是 “Multipurpose Internet Mail Extensions” 的缩写,从字面上也能看出其具有指示 “Extension” 的机能) ;
  • OEBPS 文件夹:虽暂不知其确切含义,但应存放 ePub 的文字、图片以及其他的界面数据;
    • content.opf 文件:里面存放的应该是目录信息——或是定义各种文件的“次序”;
    • Images StylesText 文件夹:明显分别存放图片、层叠样式表和文字数据;
    • toc.ncx 文件:可能是真正的目录 (“toc” 是 “table of contents” 的缩写)。

接下来我们将挨个分析。

Round IV.I. 容器

先看 META-INF/container.xml

[littleye233@lymjrolt test_epub]$ file META-INF/container.xml
META-INF/container.xml: XML 1.0 document, ASCII text

输出其内容:

<?xml version="1.0" encoding="UTF-8"?>
<container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container">
    <rootfiles>
<rootfile full-path="OEBPS/content.opf" media-type="application/oebps-package+xml"/>    </rootfiles>
</container>

显然是一个标准的 XML 文件,其中我们可以注意到 /container/rootfiles/rootfile[@class='full-path']1 中定义了一个我们之前认定的目录文件,但此处可以规范化,故这个文件在大多数 ePub 档中应该是相同的。

Round IV.II. 文件类型定性

接下来看 mimetype 文件:

[littleye233@lymjrolt test_epub]$ cat mimetype
application/epub+zip

这也是相当显然的,也不再赘述。

Round IV.III. 目录?

再看 OEBPS/content.opf

[littleye233@lymjrolt test_epub]$ file OEBPS/content.opf
OEBPS/content.opf: XML 1.0 document, Unicode text, UTF-8 text, with very long lines (504)

这也是一个 XML 文件,令人惊讶的是 file 命令竟能看出这个文件中最长的行有 504 个字符,属实让人害怕。

点此查看 `OEBPS/content.opf` 的全部内容 (已经过格式化)
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://www.idpf.org/2007/opf" version="2.0" unique-identifier="uid">
  <metadata xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf">
    <dc:title opf:file-as="kafeiguantuilishijianbuxilie(quansiben)">咖啡馆推理事件簿系列(全四本)</dc:title>
    <dc:language>zh</dc:language>
    <dc:identifier id="uid">3899198450</dc:identifier>
    <dc:creator opf:file-as="(ri)gangqizuomo">(日)冈崎琢磨</dc:creator>
    <dc:date opf:event="publication">2018-03-15</dc:date>
    <!-- Extra MetaData from RESC
<dc:coverage/>
-->
    <meta name="cover" content="x_cover-image"/>
    <meta name="output encoding" content="utf-8"/>
    <meta name="primary-writing-mode" content="horizontal-lr"/>
    <!-- BEGIN INFORMATION ONLY
<meta name="Cover ThumbNail Image" content="Images/image00466.jpeg" />
<meta name="Drm Ebookbase Book Id" content="0006008690412" />
<meta name="ASIN" content="B07BFTVX98" />
<meta name="Creator-Software" content="201" />
<meta name="Author-Pronunciation" content="(ri)gangqizuomo" />
<meta name="Embedded-Record-Count" content="11" />
<meta name="Unknown_(403)_(hex)" content="00" />
<meta name="HasFakeCover" content="0" />
<meta name="Creator-Major-Version" content="2" />
<meta name="cdeType" content="EBOK" />
<meta name="override-kindle-fonts" content="false" />
<meta name="CDEContentKey" content="B07BFTVX98" />
<meta name="Compression-Upgraded" content="Source-Target:c1-c2 KT_Version:2.9 Build:0805-4a0c57c" />
<meta name="HD-Media-Containers-Info" content="2400x3840:0-11|" />
<meta name="548 (hex)" content="496e4d656d6f7279" />
<meta name="Unknown_(407)_(hex)" content="0000000000000000" />
<meta name="Amazon_Creator_Info" content="kjw" />
<meta name="Clipping-Limit" content="100" />
<meta name="Tamper-Proof-Keys_(hex)" content="01000000d000000001940000000191000000019500000001960000000197" />
<meta name="Title-Pronunciation" content="kafeiguantuilishijianbuxilie(quansiben)" />
<meta name="Creator-Minor-Version" content="9" />
<meta name="MetadataResourceURI" content="kindle:embed:000A" />
<meta name="Updated_Title" content="咖啡馆推理事件簿系列(全四本)" />
<meta name="Ownership-Type_(hex)" content="00" />
<meta name="547 (hex)" content="496e4d656d6f7279" />
<meta name="Content-Language-Tag" content="zh" />
<meta name="sample" content="0" />
<meta name="Metadata-Record-Offset" content="4294967295" />
<meta name="Creator-Build-Tag" content="0721-dedaf5" />
<meta name="Publisher-Pronunciation" content="xiandaichubanshe" />
<meta name="StartOffset" content="4294967295" />
<meta name="Watermark_(hex)" content="6174763a6b696e3a323a49396e41307a4239625565766a514961583462736b66476a394535335a51616a696368585638364447746b65544379504d504c4d75445a35524f39676b584d35515a6433694f424b5531546643766f5a62507763705a6b49486f6f366a6639785944327a4158494263536c495879676b6a38616b566e4763327a2b2b50434c454c464b2b4e30495a4556437a6331516f656f4451546b3865374a6f61696251526d6f682b7574586b3661466a554477704a3165636c68665367414a35664745413a68614f61636b496839662b61786c457733397665774b32554a57453d" />
<meta name="Text-to-Speech-Disabled" content="0" />
<meta name="Font-Signature_(hex)" content="0300000000480f08100000000000008000200000000000000000000000000000bef4edec01b701d7409440984099409c409d40a64a804c9c608160826080608b60e8618b60cd60c661aa61f361d661e9629c73df0213c9021fd90173cd01429f037e9a037e8c037e81037e9f" />
<meta name="Rental-Expiration-Time" content="0000000000000000" />
<meta name="Container_Id" content="ZkM0" />
<meta name="Mobi8-Boundary-Section" content="420" />
<meta name="Creator-Build-Number" content="0" />
END INFORMATION ONLY -->
  </metadata>
  <manifest>
    <item id="x_cover" media-type="application/xhtml+xml" href="Text/cover_page.xhtml"/>
    <item id="x_TableOfContents" media-type="application/xhtml+xml" href="Text/part0000.xhtml"/>
    <item id="x_a1cover.html" media-type="application/xhtml+xml" href="Text/part0001.xhtml"/>
    <item id="x_a1bookname" media-type="application/xhtml+xml" href="Text/part0002.xhtml"/>
    <item id="x_a1TableOfContents" media-type
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值