关于lua反编译文件中文字符显示为10进制字符的处理

关于lua反编译文件中文字符显示为10进制字符的处理

之前遇到了lua文件反编译后,中文显示的是10进制字符的问题,网上搜了下,没看到什么批量处理的方法,就自己研究用Java写了一个批量处理工具。

原理很简单,就是先把10进制的数字转换成16进制,然后再用URLDecoder解码就行了。

注:代码仅供参考,如有bug或者更优的方法,烦请留言指出。大家一起学习进步!

代码如下

package com.zzb;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URLDecoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author zhengzhibiao
 * @date 2019-12-09 14:01
 */
public class Test {

    /**
     * 匹配10进制字符的正则表达式
     */
    private static final Pattern PATTERN = Pattern.compile("(\\\\\\d{3}){3}");

    /**
     * 日期格式化
     */
    private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.ms");

    /**
     * 读取文件的目录路径
     */
    private static final String READ_DIRECTORY_PATH = "D:\\path1";

    /**
     * 写入文件的目录路径
     */
    private static final String WRITE_DIRECTORY_PATH = "D:\\path2";

    /**
     * 统计解析的文件总数
     */
    private static int COUNT = 0;

    /**
     * 解析成功的文件数量
     */
    private static int SUCCESS = 0;

    /**
     * 解析失败的文件数量
     */
    private static int FAIL = 0;



    public static void main(String[] args) {
        long startTime = System.currentTimeMillis();
        Date startDate = new Date(startTime);

        System.out.println("解析文件-开始,当前时间:" + DATE_FORMAT.format(startDate));

        start();

        long endTime = System.currentTimeMillis();
        Date endDate = new Date(endTime);

        long second = (endTime - startTime) / 1000;

        System.out.println("文件总数:" + COUNT + ",成功:" + SUCCESS + ",失败:" + FAIL);
        System.out.println("解析文件-结束,当前时间:" + DATE_FORMAT.format(endDate) + ",共耗时:" + second + "秒。");
    }



    /**
     * 开始解析
     */
    private static void start() {
        File fileDirectory = new File(READ_DIRECTORY_PATH);
        if (!fileDirectory.exists()) {
            System.out.println("[" + READ_DIRECTORY_PATH + "]目录不存在!");
            return;
        }
        if (!fileDirectory.isDirectory()) {
            System.out.println("[" + READ_DIRECTORY_PATH + "]不是一个目录!");
            return;
        }
        readDirectory(fileDirectory);
    }


    /**
     * 读取目录
     * @param fileDirectory 目录文件对象
     */
    private static void readDirectory(File fileDirectory) {
        File[] files = fileDirectory.listFiles();
        if (files == null || files.length == 0) {
            return;
        }
        for (File file : files) {
            if (file.isFile()) {
                COUNT++;
                List<String> readList = readFile(file);
                writeFile(file.getName(), readList);
                continue;
            }
            if (file.isDirectory()) {
                readDirectory(file);
            }
        }
    }



    /**
     * 一行一行读取文件
     * @param file 读取的文件对象
     * @return 读取到的字符串集合
     */
    private static List<String> readFile(File file) {
        FileInputStream fis = null;
        InputStreamReader isr = null;
        BufferedReader br = null;
        List<String> readList = new ArrayList<>();
        try {
            fis = new FileInputStream(file);
            isr = new InputStreamReader(fis, "UTF-8");
            br = new BufferedReader(isr);
            String line = "";
            while ((line = br.readLine()) != null) {
                readList.add(line);
            }
            System.out.println("读取文件[" + file.getPath() + "]-成功!");
        } catch (Exception e) {
            System.out.println("读取文件[" + file.getPath() + "]-失败:" + e.getMessage());
        } finally {
            // 注意关闭的先后顺序,先打开的后关闭,后打开的先关闭
            try {
                if (br != null) {
                    br.close();
                }
            } catch (Exception e) {

            }
            try {
                if (isr != null) {
                    isr.close();
                }
            } catch (Exception e) {

            }
            try {
                if (fis != null) {
                    fis.close();
                }
            } catch (Exception e) {

            }
        }
        return readList;
    }


    /**
     * 一行一行写入文件
     * @param fileName 文件名(带后缀)
     * @param list 需要写入的字符串集合
     */
    private static void writeFile(String fileName, List<String> list) {
        FileOutputStream fos = null;
        OutputStreamWriter osw = null;
        BufferedWriter bw = null;
        String newFilePath = WRITE_DIRECTORY_PATH + "\\" + fileName;
        try {
            File writeDirectory = new File(WRITE_DIRECTORY_PATH);
            if (!writeDirectory.exists()) {
                writeDirectory.mkdirs();
            }
            File writeFile = new File(newFilePath);
            if (!writeFile.exists()) {
                writeFile.createNewFile();
            }
            //写入中文字符时解决中文乱码问题
            fos = new FileOutputStream(writeFile);
            osw = new OutputStreamWriter(fos, "UTF-8");
            bw = new BufferedWriter(osw);
            for (String str : list) {
                String newStr = strConvert(str);
                bw.write(newStr + "\t\n");
            }
            SUCCESS++;
            System.out.println("解析文件[" + newFilePath + "]-成功!");
        } catch (Exception e) {
            FAIL++;
            System.out.println("解析文件[" + newFilePath + "]-失败:" + e.getMessage());
        } finally {
            // 注意关闭的先后顺序,先打开的后关闭,后打开的先关闭
            try {
                if (bw != null) {
                    bw.close();
                }
            } catch (Exception e) {

            }
            try {
                if (osw != null) {
                    osw.close();
                }
            } catch (Exception e) {

            }
            try {
                if (fos != null) {
                    fos.close();
                }
            } catch (Exception e) {

            }
        }
    }



    /**
     * 解析字符串
     * @param oldStr 需要解析的字符串
     * @return
     */
    private static String strConvert(String oldStr) {
        // 现在创建 matcher 对象
        Matcher matcher = PATTERN.matcher(oldStr);
        while (matcher.find()) {
            try {
                //每一个符合正则的字符串
                String str = matcher.group();
                String[] array = str.split("\\\\");
                StringBuilder sb = new StringBuilder();
                for (String s : array) {
                    if (s == null || "".equals(s)) {
                        continue;
                    }
                    s = Integer.toHexString(Integer.parseInt(s));
                    sb.append("%").append(s);
                }
                String newStr = URLDecoder.decode(sb.toString(), "UTF-8");
                str = str.replaceAll("\\\\", "\\\\\\\\");
                oldStr = oldStr.replaceAll(str, newStr);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return oldStr;
    }


}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值