某津英汉辞书 3.1.0

想了好久,感觉这么发应该没什么问题。
欢迎大家去买某津的英汉辞书,app确实挺好用的,直接走iOS或者google play支付就能用,付款也较为方便。
为了鼓励大家购买,下面准备了一些代码,只有买了正版的人才能用,使用时需要将db文件和keydata.json与代码放到同一文件夹中,并在该文件夹中执行该代码。
快买,不知道之后什么时候就用不了这个代码了!早买早享受!

pip install pycryptodome
import sqlite3
import zlib
from Crypto.Cipher import AES
from binascii import unhexlify
import hmac
import hashlib
from binascii import hexlify
import struct
import base64
import json
from io import BytesIO



def decrypt_and_decompress_db(db_name, key_hex):
    key = unhexlify(key_hex)
    cipher = AES.new(key, AES.MODE_ECB)
    
    def decrypt_aes_ecb(data):
        if len(data) % 16 != 0:
            print("Data length should be multiple of 16.")
            return None
        return cipher.decrypt(data)
    
    def decompress_data(data):
        try:
            return zlib.decompress(data)
        except zlib.error:
            return decompress_corrupted(data)
    def decompress_corrupted(data):
        d = zlib.decompressobj(zlib.MAX_WBITS | 32)
        f = BytesIO(data)
        result_str = b''
        buffer = f.read(1)
        try:
            while buffer:
                result_str += d.decompress(buffer)
                buffer = f.read(1)
        except zlib.error:
            pass
        return result_str
    
    conn = sqlite3.connect(f'{db_name}.db')
    cursor = conn.cursor()
    
    decrypted_conn = sqlite3.connect(f'{db_name}_decrypt.db')
    decrypted_cursor = decrypted_conn.cursor()
    
    cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name != 'sqlite_sequence';")
    tables = cursor.fetchall()
    
    for table in tables:
        table_name = table[0]
        cursor.execute(f"PRAGMA table_info({table_name});")
        columns_info = cursor.fetchall()
        
        create_statement = f"CREATE TABLE IF NOT EXISTS {table_name} ("
        create_statement += ", ".join([f"{col[1]} {col[2]}" for col in columns_info])
        create_statement += ");"
        
        decrypted_cursor.execute(create_statement)
        
        columns = [col[1] for col in columns_info]
        insert_statement = f"INSERT INTO {table_name} ({', '.join(columns)}) VALUES ({', '.join(['?'] * len(columns))});"
        
        body_index = None
        for idx, col in enumerate(columns_info):
            if col[1] == 'body' or col[1] == "data":
                body_index = idx
                break
        
        if body_index is not None:
            print(f"Decrypting and decompressing 'body' column in '{table_name}' table.")
             
            cursor.execute(f"SELECT * FROM {table_name};")
            rows = cursor.fetchall()
            
            for row in rows:
                row = list(row)
                if row[body_index] is not None:
                    decrypted_body = decrypt_aes_ecb(row[body_index])
                    decompressed_body = decompress_data(decrypted_body)
                    row[body_index] = decompressed_body
                decrypted_cursor.execute(insert_statement, row)
    
    decrypted_conn.commit()
    
    conn.close()
    decrypted_conn.close()
    print(f"All data has been decrypted, decompressed and saved to '{db_name}_decrypt.db'.")
def generate_hex_representation(secret_key, data_to_sign, base64_encoded_iArr,is_big=False):
    hmac_signature = hmac.new(secret_key.encode(), data_to_sign.encode(), hashlib.sha256).digest()
    decoded_bytes = base64.b64decode(base64_encoded_iArr)
    iArr = list(struct.unpack('<' + 'I' * (len(decoded_bytes) // 4), decoded_bytes))
    iArr2 = list(struct.unpack('<' + 'I' * (len(hmac_signature) // 4), hmac_signature))
    
    limit = len(iArr)
    iArr3 = [0] * limit
    for i8 in range(limit):
        iArr3[i8] = iArr[i8] ^ iArr2[i8] ^ iArr2[i8 + 4]
    if is_big:
        bytes_data = struct.pack('>' + 'I' * len(iArr3), *iArr3)
        hex_representation = hexlify(bytes_data).decode('ascii')
    else:
        bytes_data = struct.pack('<' + 'I' * len(iArr3), *iArr3)
        hex_representation = hexlify(bytes_data).decode('ascii')
    
    return hex_representation


secret_key = base64.b32decode('KNKUYMLWHBLE26LBNJQW43DKKZXGSZTDJE2GQUTVKR4W2R2ENVKE4VTZLFHTQQSZ').decode()
keydata = json.loads(open("keydata.json").read())
for single_key in keydata["keys"]:
    base64_encoded_iArr = keydata["keys"][single_key]["code"]
    data_to_sign = str(keydata["keys"][single_key]["expires"]) + keydata["iid"]
    if single_key == "audio":
        db_key = generate_hex_representation(secret_key,data_to_sign,base64_encoded_iArr,is_big=True)
        decrypt_and_decompress_db("haudio",db_key)
    else:
        db_key = generate_hex_representation(secret_key,data_to_sign,base64_encoded_iArr)
        decrypt_and_decompress_db(single_key,db_key)
9 Likes

同时也很好奇,论坛存在过某种,电子词典更新年代很近还可以花钱买的时候做数据提取(不是爬取)共享的吗?或者有人经历过版权方的铁拳吗?这种提取原数据并放出来的行为看上去有些危险。

感觉又要开辟一个新纪元 :goutou:

mdx对很多人来说,其实不是那么容易用。本坛也太小了,又不牟利,看词典的点击量,非常少,对销售的影响可以忽略不计。要打击其实应该打击搬去淘宝、微信倒卖的那些倒爷。

因为有所谓避风港原则,要追究也只能追究发词典的人,但是网海茫茫,很难追究。假如造成的可能的损失可以推断很小,追究起来得不偿失。

Pdawiki的会员有几十万,点击量也有几十万。可以推断会有影响的。最后怎样呢?很难追究个别发词典的人,太麻烦。跑了和尚跑不了庙,最后干脆强制Pdawiki关闭词典版块。

倒是大规模发国学古籍(整理过的,不然古籍不可能有版权)电子书的人在多年前被起诉过,不过结局不知如何。

老兄这种发了代码让人抓自己买的词典的,肯定没问题。

我不需要。纯粹看热闹。

4 Likes

版权方的铁拳是没有的,应用加固增加反逆向数据混淆加密是有的。 :goutou:

1 Like

确实,MDX格式不像原本的数据库那样容易二次(盈利)利用,除了“淘宝、微信倒卖的那些倒爷”。
总体上比较小众。

感觉国内买牛津英汉辞书的人是小众中的小众。大部分像我一样的正版用户买的都是海笛。
但是海笛数据处理的不好,有残缺;其次是强行联网。
不过牛津10双解版app终于没有给海笛,已经可以离线了。

1 Like

向大神学习中

用了以后可以怎么样?或者说有什么好处? :smiley:

海迪这么厉害吗?我之前没接触过,不知道这么有名

自己解密了做字典

2 Likes

我差点挨上…

1 Like

传播分享mdx就像工具改装,有了新的改装方法以后变得更加易用,有同样爱好的坛友们在一起交流改装或使用经验。大部分人对这些事都没那么热衷,要么手头有什么就对付用什么,不合用买新的就是了。改装终究是小众的爱好,影响不了市场。

来个mdx文件吗

1 Like

好像手机上没找到文件。是在哪个文件夹里面?