我们可以通过黑鸟网页端把来自其它码表的fit文件上传到黑鸟App.
黑鸟App的fit上传功能并不完善,来自迈金码表的fit文件在上传时会遇到导入失败的错误.
我们只要改变fit文件中的设备名和设备制造商,就可以把来自于迈金的fit文件伪装成来自佳明的fit文件, 从而骗过检测系统成功上传记录到黑鸟App.
有两种办法改变fit文件的设备名和设备制造商:
法1:
在 https://www.fitfiletools.com/#/top 中, 改变fit的device name. 经测试改为 edge500_china 后可以成功将迈金码表的fit文件上传到黑鸟App.
法2:
使用如下的python代码进行转换. 以下代码强制把fit文件的设备名设置成 gammin 1030.
使用时, 把如下的python代码保存成 change_name.py
放置在待转换的fit文件所在的文件夹中, 运行python chainge_name.py
即可.
import struct import os import fitparse import glob def modify_fit_to_garmin_edge500(input_file, output_file): """ 将 FIT 文件的 manufacturer 和 garmin_product 修改为 Garmin Edge 500 China """ # 读取原始 FIT 文件 fitfile = fitparse.FitFile(input_file) # 打开原文件读取二进制数据 with open(input_file, 'rb') as f: data = bytearray(f.read()) # 查找并修改 file_id 消息中的字段 for record in fitfile.get_messages('file_id'): print("原始文件信息:") for field in record: print(f" {field.name}: {field.value} (类型: {type(field.value)})") # 修改 manufacturer 字段 (1 = garmin) if field.name == 'manufacturer': old_val = get_field_numeric_value(field) if old_val is not None and old_val != 1: print(f"修改 manufacturer: {old_val} -> 1 (garmin)") modify_field_in_binary(data, old_val, 1, 2) # 修改 garmin_product 字段 (1030 = edge500_china) if field.name == 'garmin_product': old_val = get_field_numeric_value(field) if old_val is not None and old_val != 1030: print(f"修改 garmin_product: {old_val} -> 1030 (edge500_china)") modify_field_in_binary(data, old_val, 1030, 2) # 重新计算 CRC 校验和 update_crc(data) # 写入新文件 with open(output_file, 'wb') as f: f.write(data) print(f"已将 FIT 文件转换为 Garmin Edge 500 China: {output_file}") def get_field_numeric_value(field): """ 获取字段的数值,处理不同数据类型 """ if isinstance(field.value, int): return field.value elif isinstance(field.value, str): # 如果是字符串,尝试从原始值获取 if hasattr(field, 'raw_value') and isinstance(field.raw_value, int): return field.raw_value return None def modify_field_in_binary(data, old_value, new_value, field_size): """ 在二进制数据中查找并替换字段值 """ if not isinstance(old_value, int) or not isinstance(new_value, int): print(f" 跳过非整数值: {old_value}") return if field_size == 2: old_bytes = struct.pack('<H', old_value) # 小端序 2 字节 new_bytes = struct.pack('<H', new_value) elif field_size == 4: old_bytes = struct.pack('<I', old_value) # 小端序 4 字节 new_bytes = struct.pack('<I', new_value) else: return # 查找并替换 pos = data.find(old_bytes) if pos != -1: data[pos:pos+field_size] = new_bytes print(f" 在位置 {pos} 替换了字段值") else: print(f" 未找到要替换的字节序列") def update_crc(data): """ 更新 FIT 文件的 CRC 校验和 """ if len(data) >= 2: crc = calculate_crc(data[:-2]) data[-2:] = struct.pack('<H', crc) def calculate_crc(data): """ 计算 FIT 文件的 CRC-16 校验和 """ crc = 0 for byte in data: crc ^= byte for _ in range(8): if crc & 1: crc = (crc >> 1) ^ 0xA001 else: crc >>= 1 return crc & 0xFFFF if __name__ == "__main__": for file in glob.glob("./*.fit"): print(f"Processing file: {file}") output_file = file.replace('.fit', '_GM.fit') modify_fit_to_garmin_edge500(file, output_file)
本文作者:JiangOil
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!