Java版文件CRC32校验值修改算法

记录一下Java版CRC32修改算法

import java.io.*;
import java.util.zip.*;

public class Crc32Editor
{
	private static long[] crc32Table = new long[256];

	static {
		long crcValue;
		for (int i = 0; i < 256; i++)
		{
			crcValue = i;
			for (int j = 0; j < 8; j++)
			{
				if ((crcValue & 1) == 1)
				{
					crcValue = crcValue >> 1;
					crcValue = 0x00000000edb88320L ^ crcValue;
				}
				else
				{
					crcValue = crcValue >> 1;
				}
			}
			crc32Table[i] = crcValue;
		}
	}

	public static boolean editFile(String path, String newCrc32Str)
	{
		try
		{
			long newCrc = Long.valueOf(newCrc32Str, 16);
			while (getFileCrc32(path) != newCrc)
			{
				FileOutputStream fos = new FileOutputStream(path, true);
				fos.write(getAddBytes(getFileCrc32(path), newCrc));
				fos.close();
			}
			return true;
		}
		catch (Exception e)
		{
			return false;
		}
	}

	public static long getFileCrc32(String path)
	{
		long crcValue = -1;
		try
		{
			CRC32 crc = new CRC32();
			FileInputStream fis = new FileInputStream(path);
			int i;
			byte[] buf = new byte[1024];
			while ((i = fis.read(buf)) != -1)
			{
				crc.update(buf, 0, i);
			}
			fis.close();
			crcValue = crc.getValue();
		}
		catch (Exception e)
		{
		}
		return crcValue;
	}

	private static byte[] getAddBytes(long oldCrc32, long newCrc32)
	{
		byte[] result = new byte[4];
		int[] index = new int[4];
		long[] crackXor = new long[4];
		long[] trueXor = new long[4];

		crackXor[3] = newCrc32 ^ 0x00000000ffffffffL;
		index[3] = getIndex(crackXor[3] >> 24);

		crackXor[2] = crackXor[3] ^ crc32Table[index[3]];
		index[2] = getIndex(crackXor[2] >> 16);

		crackXor[1] = crackXor[2] ^ (crc32Table[index[2]] >> 8);
		index[1] = getIndex(crackXor[1] >> 8);

		crackXor[0] = crackXor[1] ^ (crc32Table[index[1]] >> 16);
		index[0] = getIndex(crackXor[0]);

		trueXor[0] = oldCrc32 ^ 0x00000000ffffffffL;
		result[0] = getByte(trueXor[0], index[0]);

		trueXor[1] = getXor(trueXor[0], result[0]);
		result[1] = getByte(trueXor[1], index[1]);

		trueXor[2] = getXor(trueXor[1], result[1]);
		result[2] = getByte(trueXor[2], index[2]);

		trueXor[3] = getXor(trueXor[2], result[2]);
		result[3] = getByte(trueXor[3], index[3]);

		return result;
	}

	private static long getXor(long beforeXor, byte b)
	{
		return crc32Table[(int) ((beforeXor ^ b) & 0xff)] ^ (beforeXor >> 8);
	}

	private static int getIndex(long start)
	{
		for (int i = 0; i < crc32Table.length; i++)
		{
			if ((crc32Table[i] >> 24) == start)
			{
				return i;
			}
		}
		return 0;
	}

	private static byte getByte(long beforeXor, int index)
	{
		for (byte b = -128; b < 127; b++)
		{
			if (index == (int) ((beforeXor ^ b) & 0xff))
			{
				return b;
			}
		}
		return 0;
	}

}

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

'小五'

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值