You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python实现大JSON文件中通知本地化文本替换求助

问题描述

我需要自动替换一个30MB大型JSON文件中的字符串,文件结构示例如下:

通知部分:

"local_notifications": [
    {
      "is_enabled": false,
      "notification_type": "basic",
      "notification_title": "localised_strings.show_name_debug_lobbies",
      "notification_body": "localised_strings.show_desc_debug_lobbies",
      "schedule": {
        "schedule_type": "dynamic",
        "elapsed_time": [
          {
            "days": 0,
            "hours": 0,
            "minutes": 1
          }
        ]
      },
      "priority": 0,
      "priority_override": false,
      "id": "debug_notification"
    }
]

本地化字符串部分:

"localised_strings": [
    {
      "text": "Debug lobbies",
      "id": "show_name_debug_lobbies"
    },
    {
      "text": "Debug lobbies 2",
      "id": "show_desc_debug_lobbies"
    }
 ]

目标是将notification_title和notification_body字段中的值(格式为localised_strings.xxx)替换为localised_strings数组中对应id的text值。我已有解密该加密文件的Python代码,需要在此基础上实现替换功能。

解密代码如下:

import argparse
from argparse import RawTextHelpFormatter

xor_key = [0x61, 0x23, 0x21, 0x73, 0x43, 0x30, 0x2c, 0x2e]

description = ('Decrypt or encrypt content_v1 of Fall Guys: Ultimate Knockout\n'
'content_v1 is usually found inside %UserProfile%\AppData\LocalLow\Mediatonic\FallGuys_client')

argument_parser = argparse.ArgumentParser(description=description, formatter_class=RawTextHelpFormatter)

argument_parser.add_argument('input_file', help='content_v1 or a valid JSON file')
argument_parser.add_argument('output_file')

arguments = argument_parser.parse_args()

content = bytearray()
content_idx = 0

try:
  with open(arguments.input_file, 'rb') as input_file:
    while (byte := input_file.read(1)):
      content += bytes([ord(byte) ^ xor_key[content_idx % (len(xor_key))]])
      content_idx += 1
except (IOError, OSError) as exception:
  print('Error: could not read input file')
  exit()

try:
  with open(arguments.output_file, 'wb') as output_file:
    output_file.write(content)
except (IOError, OSError) as exception:
  print('Error: could not create output file')
  exit()
解决方案

我们可以将解密、JSON处理、加密(可选)整合到一个脚本中,步骤如下:

  • 解密文件:使用已有逻辑读取并解密加密文件,得到可解析的JSON文本。
  • 构建本地化映射:从JSON中提取localised_strings,创建id到text的字典,实现快速查找。
  • 替换通知字段:遍历local_notifications条目,解析标题和内容中的ID,替换为对应本地化文本。
  • 输出结果:可选择输出修改后的解密JSON,或重新加密后保存。

完整代码

import argparse
import json
from argparse import RawTextHelpFormatter

xor_key = [0x61, 0x23, 0x21, 0x73, 0x43, 0x30, 0x2c, 0x2e]

description = ('Decrypt, replace localisation strings, and optionally re-encrypt content_v1 of Fall Guys: Ultimate Knockout\n'
'content_v1 is usually found inside %UserProfile%\AppData\LocalLow\Mediatonic\FallGuys_client')

argument_parser = argparse.ArgumentParser(description=description, formatter_class=RawTextHelpFormatter)
argument_parser.add_argument('input_file', help='content_v1 or a valid JSON file')
argument_parser.add_argument('output_file')
argument_parser.add_argument('--reencrypt', action='store_true', help='Re-encrypt the modified JSON before saving')

args = argument_parser.parse_args()

def xor_crypt(data):
    """XOR加密/解密通用函数"""
    content = bytearray()
    content_idx = 0
    for byte in data:
        content.append(byte ^ xor_key[content_idx % len(xor_key)])
        content_idx += 1
    return content

# 1. 读取并解密文件
try:
    with open(args.input_file, 'rb') as f:
        encrypted_data = f.read()
    decrypted_data = xor_crypt(encrypted_data)
except (IOError, OSError) as e:
    print(f'读取输入文件出错: {e}')
    exit(1)

# 2. 解析JSON并执行替换
try:
    json_data = json.loads(decrypted_data.decode('utf-8'))
    
    # 构建本地化ID到文本的映射表
    localisation_map = {}
    for item in json_data.get('localised_strings', []):
        loc_id = item.get('id')
        if loc_id:
            localisation_map[loc_id] = item.get('text', '')
    
    # 遍历通知列表替换字段
    for notification in json_data.get('local_notifications', []):
        # 处理标题字段
        title_key = notification.get('notification_title', '')
        if title_key.startswith('localised_strings.'):
            target_id = title_key.split('.', 1)[1]
            notification['notification_title'] = localisation_map.get(target_id, title_key)
        
        # 处理内容字段
        body_key = notification.get('notification_body', '')
        if body_key.startswith('localised_strings.'):
            target_id = body_key.split('.', 1)[1]
            notification['notification_body'] = localisation_map.get(target_id, body_key)
    
    # 生成修改后的JSON字节数据
    modified_json = json.dumps(json_data, indent=2, ensure_ascii=False)
    modified_bytes = modified_json.encode('utf-8')

except json.JSONDecodeError as e:
    print(f'解析JSON出错: {e}')
    exit(1)
except Exception as e:
    print(f'处理数据出错: {e}')
    exit(1)

# 3. 保存结果(可选加密)
try:
    output_data = xor_crypt(modified_bytes) if args.reencrypt else modified_bytes
    with open(args.output_file, 'wb') as f:
        f.write(output_data)
    print(f'处理完成,结果已保存到 {args.output_file}')
except (IOError, OSError) as e:
    print(f'写入输出文件出错: {e}')
    exit(1)

使用说明

  • 输出修改后的解密JSON:
    python script.py 输入文件路径 输出文件路径
    
  • 修改后重新加密输出:
    python script.py 输入文件路径 输出文件路径 --reencrypt
    

注意事项

  • 30MB的JSON文件解析会占用一定内存,确保系统有足够资源(8GB以上内存无压力)。
  • 若实际JSON结构与示例有差异,需调整代码中对应的字段名称。
  • 处理前请备份原始文件,避免数据丢失。

内容的提问来源于stack exchange,提问作者Didoub74

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 04:45:29