批處理新手入門導讀[視頻教程]批處理基礎視頻教程[視頻教程]VBS基礎視頻教程
[批處理文件精品]批處理版照片整理器[批處理文件精品]純批處理備份&還原驅動在線第三方下載
返回列表 發帖

[原創教程] 有道離線字典的拆解

本帖最后由 523066680 于 2016-6-8 22:42 編輯

去年就開始拆了,發現譯文信息里一部分翻譯是明文,一部分又是給出了另一個字典的索引
要自己挖,還分層的挖,煩了就停了。今年想起來又接著搞,挖成明文后對數據格式化,改
成Perl的hash/array復合結構。分成了五六個腳本吧,拆解部分不一一張貼,主要說方法。

準備

        安裝 有道字典增強版 (下載的V6.2),安裝目錄下會有 localdicts 文件夾,包含字典文
    件以及索引文件。
    1. C:\USERS\%USERNAME%\APPDATA\LOCAL\YOUDAO\DICT\APPLICATION\LOCALDICTS
    2.     2016/06/06  09:20    <DIR>          ..
    3. 2016/06/06  09:20        28,460,334 21EC.ydic
    4. 2016/06/06  09:20         8,094,269 basicCE.ydic
    5. 2016/06/06  09:20        16,692,913 basicEC.ydic
    6. 2016/06/06  09:20         3,737,882 CE.idx
    7. 2016/06/06  09:20               250 CE.ifo
    8. 2016/06/06  09:20         7,991,892 EC.idx
    9. 2016/06/06  09:20               334 EC.ifo
    10. 2016/06/06  09:20         9,900,103 newCE.ydic
    11. 2016/06/06  09:20         5,475,078 phrase.ydic
    12. 2016/06/06  09:20        42,980,352 sentenceDict.sql
    復制代碼
    .ifo 文件是摘要信息(比如某個字典有多少單詞量)
    .idx 文件分兩部分,第一部分是索引數據,第二部分是單詞內容
    .ydic 文件是翻譯信息

分析

        先針對英漢字典(EC.idx basicCE.ydic)

        比較業余,用了幾種方法,就.idx文件來說,已經知道是索引,將其轉成16進制按N組一行的方式
    排列(用的Perl提取劃分,雖然我知道有些工具更好用),發現其中的規律是,每12個字節為一組
    數據,在一組里面,每4個字節合為一個數值(低位在前,這是后來發現的)。以及按4列16進制值顯示后
    發現到了某個位置規律就不一樣了。
    1. 1057288 16 6a 39 00
    2. 1057289 83 b6 fe 00
    3. 1057290 17 00 00 00
    4. 1057291 1b 6a 39 00
    5. 1057292 9a b6 fe 00
    6. 1057293 17 00 00 00  //以下為第二部分,沒有明顯規律
    7. 1057294 37 73 71 65
    8. 1057295 63 75 37 73
    9. 1057296 75 60 64 37
    10. 1057297 74 7f 72 75
    11. 1057298 37 74 62 79
    復制代碼
    然后對ydic分析字節頻率,以下是頻率較高的字節,左邊是出現的次數
    00337934 ac
    00352074 6d
    00352432 6b
    00378084 22
    00477148 f5
    00563980 2a
    00567693 75
    00692001 21
    00997268 33
    02211802 32

    然而并沒有什么卵用,6d 和 6b 33 和 32 是什么? m k 3 2 ?寫了一個腳本: 輸入16進制值,試轉UTF、GBK
    1. input:6d 6b 33 32
    2. mk32    gbk     109
    3. mk32    big5    109
    4. mk32    utf8    109
    5. 歭社    utf16-le        27501
    6. not utf16-be
    復制代碼
    但是好在想起了單詞數量,在ifo文件:WordCount:352431
    6b 和 6d的出現次數和這個非常接近,可能作為分隔符。


解碼:

    隨便指定一個單詞,比如 area,用類似二分法的方式,斷開網絡,對ydic翻譯文件對半裁剪。
    用有道詞典查詢該單詞,不能查到就提取另一半/繼續對半裁剪,最后定位數據:
    6b 32 60 32 2a 32 37 de a5 d9 89 62 79 d9 89 32 3c 32 75 32 2a 4b 32 7e 3e 33 33 30 f5 9c aa f5 8f 8f ff ac 9c
    f5 8c a0 f5 9c aa ff ac 8b f9 8d b2 f7 b7 bf ff ac 8b f8 9c 93 f5 8b a4
    32 4d 3c 32 75 68 32 2a 32 21 33 22 26 22 29 27
    29 23 26 33 26 20 20 32 3c 32 75 68 32 2a 32 22 33 23 26 23 26 23 29 23 33 23 21 27 23 32 6d

    offset: 0d6130
    length: 0x6c

    將翻譯內容:“n. 區域,地區;面積;范圍”, 試轉為不同編碼
    gbk: 6e 2e 20 c7 f8 d3 f2 a3 ac b5 d8 c7 f8 a3 bb c3 e6 bb fd a3 bb b7 b6 ce a7
    big5: 6e 2e 20 3f b0 ec a1 41 a6 61 3f a1 46 ad b1 3f a1 46 ad 53 3f
    utf8: 6e 2e 20 e5 8c ba e5 9f 9f ef bc 8c e5 9c b0 e5 8c ba ef bc 9b e9 9d a2 e7 a7 af ef bc 9b e8 8c 83 e5 9b b4
    utf16-le: 6e 0 2e 0 20 0 3a 53 df 57 c ff 30 57 3a 53 1b ff 62 97 ef 79 1b ff 3 83 f4 56

    總結出:采用UTF8編碼,并做了簡單的處理,hex的高位如果是奇數,高位-1,否則高位+1 , 還原數據:
    {"p":"'εəriə","e":["n.## 區域,地區;面積;范圍"],"ex":"1#26297936#600","ex":"2#3636393#3173"}

    "ex":"1#26297936#600"  表示引用字典 21EC.ydic 的數據,offset 為 26297936,600是數據長度
    "ex":"2#3636393#3173" 表示引用字典 phrase.ydic的數據,offset 為 3636393,3173是數據長度

    用二分法鎖定字節區域是碰了運氣,因為有很多數據都是引用另一個字典,再繞一點都會煩得不行。


現在回去看idx文件:

好像也是通過對半截取的方式,找到了對應的單詞,因為,如果單詞或者索引刪掉了,會導致搜不到。
(去年探索的,具體忘了。。。)加密方式和譯文的一樣。

總結:
     idx文件,第一部分為索引,索引數據長度 = 352431(單詞量) * 12(數據段) = 4229172
4個字節為一個值,低位在前。后面部分為單詞,單詞部分沒有劃分符,根據索引進行提取劃分,
單詞部分采用非常簡單的加密:高位奇數時-1,偶數時+1

00 00 00 00 第一單詞起點
00 00 00 00 譯文起點
16 00 00 00 譯文長度
06 00 00 00 第二單詞起點
16 00 00 00 譯文起點
16 00 00 00 譯文長度
0b 00 00 00 。。。
2c 00 00 00
16 00 00 00

拆解
此處略過,因為是不同時間去折騰的,分了多個腳本和步驟,再整理一遍真是煩

轉為明文后的字典下載地址

http://523066680.ys168.com/ [臨時]文件夾
Youdao_En_Cn_PerlStruct 202016-06.7z
Youdao EN2CN OneFile 2016-06.7z

字典搜索示例
  1. use Encode;
  2. use YAML 'Dump';
  3. my $PATH = "D:\\Local\\Dict\\Youdao\\Analyse_EC";
  4. open READ,"<:raw", "$PATH\\EN2CN.txt";
  5. my $s;
  6. our $data;
  7. while ($s = <READ>)
  8. {
  9.     if ($s=~/^words :/i)
  10.     {
  11.         $s=~/^(.+) \: (.*)\r?\n/i;
  12.         eval "\$data = $2";
  13.         delete $data->{'pr'};      #不顯示“相關詞組”信息
  14.         print utf8_to_gbk( Dump($data) );
  15.     }
  16. }
  17. close READ;
  18. sub utf8_to_gbk
  19. {
  20.     return encode('gbk', decode('utf8', $_[0]));
  21. }
復制代碼
顯示結果
---
e:
  - n. 字(word的復數);話語;言語
  - v. 用言語表達(word的三單形式)
p: w?:dz


音標包含一些gbk以外的符號,在終端顯示不全
2

評分人數

綜合型編程論壇
Writing Code That Nobody Else Can Read.

本帖最后由 523066680 于 2016-6-7 12:38 編輯

我覺得我花了好多時間做了一件非常沒有意義的事情……  但是做了又想把它做完整。
現在我可以在終端快速取詞了 grep也行,perl腳本也行(平均0.5秒),后臺不需要多開一個翻譯軟件,不需要網絡通暢

感謝有道詞典沒有用什么更進一步的加密。
其他離線字典比如詞霸、圖靈格斯、bing、海詞 的,因為知識量不夠所以放棄了
綜合型編程論壇
Writing Code That Nobody Else Can Read.

TOP

本帖最后由 codegay 于 2016-6-7 16:28 編輯

你真是太NB了。

sqlite3的應用很普遍。
這篇博客寫的5.x 有點老了。http://www.cnblogs.com/catcherx/p/3269628.html

sentenceDict.sql 里的東西是什么?
1

評分人數

去學去寫去用才有進步。安裝python3代碼存為xx.py 雙擊運行或右鍵用IDLE打開按F5運行

TOP

本帖最后由 523066680 于 2016-6-7 17:42 編輯

回復 3# codegay


    sentenceDict.sql  全是句子,記得當時也用數據庫軟件打開看過。明文。
綜合型編程論壇
Writing Code That Nobody Else Can Read.

TOP

厲害,要是戰爭年代就是密碼破譯的天才。
1

評分人數

TOP

回復 3# codegay
sqlite相當不錯,安卓幾乎都是這種輕型數據庫。功能單一,很適合做單機。

TOP

可惜沒有現成程序
每次回帖、謝謝!辛苦了。

TOP

靈格斯有現成的軟件搞定
每次回帖、謝謝!辛苦了。

TOP

返回列表
36选7开奖结果今天福建