You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

含特殊字符文件的GitHub REST API SHA校验异常问题求助

解决含特殊字符文件SHA校验不一致的问题

问题背景

当前代码依赖二次校验areReallyEqual才能正确判断含特殊字符(如ñ、é、à)的文件是否与远程仓库文件一致,无特殊字符的文件则无需此逻辑。核心问题出在SHA值的计算逻辑不符合GitHub的规则。

问题根源

GitHub计算文件SHA的规则是基于blob <字节长度>\x00<文件内容>的二进制数据生成SHA1,其中字节长度是文件内容以UTF-8编码后的实际字节数。但现有GitHubCrypto.getSha方法中,fileContent.length获取的是字符串的字符数——对于UTF-8中占多字节的特殊字符(比如ñ占2字节、é占2字节),字符数≠字节数,导致构建的blob格式错误,最终生成的SHA与GitHub返回的repositoryFile.sha不匹配。

解决方案:修正SHA计算逻辑

修改GitHubCrypto.getSha方法,正确计算UTF-8字节长度,并按照GitHub的二进制规则生成SHA:

class GitHubCrypto {
  /**
   * @param {string} fileContent
   * @returns {string} SHA1 hash string
   */
  static getSha(fileContent) {
    // 将字符串编码为UTF-8字节数组,获取真实字节长度
    const encoder = new TextEncoder();
    const contentBytes = encoder.encode(fileContent);
    const byteLength = contentBytes.length;

    // 构建GitHub要求的blob前缀:"blob <字节长度>\x00"
    const prefixStr = `blob ${byteLength}\x00`;
    const prefixBytes = encoder.encode(prefixStr);

    // 合并前缀和内容字节数组,得到完整的blob二进制数据
    const blobData = new Uint8Array(prefixBytes.length + contentBytes.length);
    blobData.set(prefixBytes);
    blobData.set(contentBytes, prefixBytes.length);

    // 针对二进制数据计算SHA1
    // 注意:如果你的Sha1.hash仅支持字符串输入,替换为以下两行:
    // const blobStr = String.fromCharCode(...blobData);
    // const sha = Sha1.hash(blobStr);
    const sha = Sha1.hash(blobData);
    return sha;
  }
}

额外验证点

  1. 确保Sha1.hash方法支持处理Uint8Array类型的二进制数据,如果原实现仅支持字符串,使用String.fromCharCode(...blobData)将字节数组转换为二进制字符串后传入。
  2. 确认getScriptInternalFiles中获取的文件内容是UTF-8编码(当前已设置Accept-Charset: utf-8,无需调整)。
  3. 远程文件下载逻辑fetchGitHubGetUrl需保证返回的是原始UTF-8字节内容,避免编码转换导致字节不一致。

修改完成后,直接对比internalFileTextSha与repositoryFile.sha即可,无需二次校验,特殊字符文件的SHA计算将与GitHub完全一致。

内容的提问来源于stack exchange,提问作者Xavier Peña

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 19:35:15