FIT文件CRC校验

校验FIT文件CRC代码做个记录,分为两步先校验头部然后再校验整个FIT文件。校验头部不是必需的看个人需要吧。为了偷懒使用Okio库,还有计算CRC的时候用的Garmin的FitSDK。

public class FitUtils {
    /**
     * 校验Fit文件,首先校验头部然后校验数据
     *
     * @param file
     * @return
     */
    public static boolean checkFitFile(File file) {
        BufferedSource source = null;
        try {
            final int MAX_HEADER_LEN = 14;
            source = Okio.buffer(Okio.source(file));
            byte[] header = new byte[MAX_HEADER_LEN - 2];
            header[0] = source.readByte();
            int headerLen = header[0];
            if (headerLen <= 0 || headerLen > MAX_HEADER_LEN)
                return false;
            source.read(header, 1, header.length - 1); //去除头长度和crc
            //验证头部
            if (headerLen == MAX_HEADER_LEN) {
                short fileCrc16 = source.readShortLe();
                if (fileCrc16 != 0) {    //FIT允许HEADER的CRC为0
                    int crc16 = getCRC16(header, 0, header.length);
                    if (crc16 != fileCrc16)
                        return false;
                }
            }
            //校验数据
            source.close();
            source = Okio.buffer(Okio.source(file));
            int crc16ForData = 0;
            for (int crcByte = 0; crcByte < file.length() - 2; crcByte++) {
                crc16ForData = CRC.get16(crc16ForData, source.readByte());
            }
            short originCRC16 = source.readShortLe();
            return originCRC16 == (short) crc16ForData;
        } catch (IOException e) {
            if (BuildConfig.DEBUG)
                e.printStackTrace();
        } finally {
            if (source != null) {
                try {
                    source.close();
                } catch (IOException e) {
                    if (BuildConfig.DEBUG)
                        e.printStackTrace();
                }
            }
        }
        return false;
    }
    public static short getCRC16(byte[] data, int offset, int len) {
        int crc16 = 0;
        for (int index = offset; index < (offset + len); index++) {
            crc16 = CRC.get16(crc16, data[index]);
        }
        return (short) crc16;
    }
}



《架构文摘》每天一篇架构领域重磅好文,涉及一线互联网公司应用架构(高可用、高性 能、高稳定)、大数据、机器学习等各个热门领域。

posted @   架构文摘  阅读(748)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
点击右上角即可分享
微信分享提示