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