StarDictの辞書ファイル形式

WeDictで使われている辞書のファイル形式を調査。
辞書ファイルはStarDict形式で、インデックスファイル[*.idx]と定義データファイル[*.dict]に分かれている。
いろいろ探し回った結果、下記のような感じらしい。

■Dictファイル
dict.dzは、ようするに辞書の意味だけファイルをgzipで圧縮した物のようだ

dictzipという(Gzip互換)ツールがあってそれで作成するらしい。

idxファイルは

文字 00 offset(4byte) length(4byte)

という風に区切られてる気がするんだけどどうかな?

で、一応stardict 2.4.3なら解析できたようだ。

ということで、試してみた。

def indexFile = new File("test.idx")
buf = indexFile.readBytes()

def i=0
int offset = 0
def indexes = new ArrayList();
while (i<buf.length) {
	if (buf[i] == 0) {
		indexes.add(new Index(
			word:new String(buf, offset, i-offset, "UTF-8")
			, offset:parseInt(buf[i+1], buf[i+2], buf[i+3], buf[i+4])
			, length:parseInt(buf[i+5], buf[i+6], buf[i+7], buf[i+8])))
		offset = i+9
		i = i+8
	}
	
	i++
}

indexes.each {index ->
	println index;
	def defIn = new FileInputStream("test.dict")
	def buf = new byte[index.length]
	defIn.skip(index.offset)
	defIn.read(buf)
	println new String(buf, "UTF-8")
	defIn.close()
}

class Index {
	def word
	def offset
	def length
	
	String toString() {
		return "[word: " + word + ",\toffset:" + offset + ",\tlength:" + length + "]"
	}
}

def parseInt(byte b1, byte b2, byte b3, byte b4) {
	return (b1 & 0xff) * 256*256*256 + (b2 & 0xff) * 256*256 + (b3 & 0xff) * 256 + (b4 & 0xff)
}

実行結果は

[word: Oリング.フロントフォーク, offset:348932, length:51]
โอริงแผงคอ / oo ring pheengkhoo
[word: Oリング.ベルトクーリングカバー, offset:348983, length:114]
โอริงฝาครอบทางระบายอากาศ / oo ring faa khroop thaang rabaai aakaat
[word: Oリング.ベルトクーリングダクト, offset:349097, length:99]
โอริงท่อทางระบายอากาศ / oo ring thoo thaang rabaai aakaat
[word: Oリング.ムーバブルドリブン, offset:349196, length:90]
โอริงล้อปรับความเร็ว / oo ring loo prap khwaam rew
[word: Oリング.モータースタート, offset:349286, length:78]
โอริงมอเตอร์สตาร์ท / oo ring mootuu sataat
[word: QC曲線, offset:349364, length:47]
เส้นโค้งQC / sen khoong khiwsii
[word: U型ライン, offset:349411, length:55]
ไลน์รูปตัวยู / lai ruup tua yuu

こんな感じ。