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

C#如何用LINQ表达式实现支持多偏移及任意偏移的文件签名校验

实现方案

第一步:属性调整

首先将原有的单个OffSet属性替换为int[] AllowedOffsets,约定值为-1代表允许签名出现在文件任意位置,示例配置如下:

  • 仅允许偏移0:AllowedOffsets = new[] { 0 }
  • 允许偏移0和4:AllowedOffsets = new[] { 0, 4 }
  • 允许任意偏移:AllowedOffsets = new[] { -1 }

第二步:核心逻辑改造

修改后的Verify方法如下:

public FileTypeVerifyResult Verify(Stream stream)
{
    stream.Position = 0;
    byte[] allReadBytes;
    // 非任意偏移场景:仅读取需要的最大长度,减少内存占用
    if (!AllowedOffsets.Contains(-1))
    {
        var maxOffset = AllowedOffsets.Max();
        var maxSignatureLength = Signatures.Max(s => s.Length);
        var needReadLength = maxOffset + maxSignatureLength;
        // 流长度不足直接返回不匹配
        if (stream.Length < needReadLength)
        {
            return new FileTypeVerifyResult
            {
                Name = Name,
                Description = Description,
                IsVerified = false
            };
        }
        using var reader = new BinaryReader(stream);
        allReadBytes = reader.ReadBytes(needReadLength);
    }
    // 任意偏移场景:读取全流字节(大文件建议改用滑动窗口匹配,避免内存溢出)
    else
    {
        using var ms = new MemoryStream();
        stream.CopyTo(ms);
        allReadBytes = ms.ToArray();
    }

    return new FileTypeVerifyResult
    {
        Name = Name,
        Description = Description,
        IsVerified = Signatures.Any(signature =>
        {
            // 任意偏移匹配逻辑
            if (AllowedOffsets.Contains(-1))
            {
                if (allReadBytes.Length < signature.Length) return false;
                // 遍历所有可能的起始位置匹配
                for (int i = 0; i <= allReadBytes.Length - signature.Length; i++)
                {
                    var match = true;
                    for (int j = 0; j < signature.Length; j++)
                    {
                        if (allReadBytes[i + j] != signature[j])
                        {
                            match = false;
                            break;
                        }
                    }
                    if (match) return true;
                }
                return false;
            }
            // 固定偏移列表匹配逻辑
            return AllowedOffsets.Any(offset =>
            {
                if (offset + signature.Length > allReadBytes.Length) return false;
                return allReadBytes.Skip(offset).Take(signature.Length).SequenceEqual(signature);
            });
        })
    };
}

可选优化点

  • 处理GB级以上大文件时,任意偏移的逻辑不要直接读取全流,可以改用滑动窗口逐段匹配,降低内存占用
  • 提前对AllowedOffsets做去重、非法值过滤(除-1外不允许负数),减少不必要的比对次数
  • 短签名的任意偏移匹配可以改用KMP等字符串匹配算法,提升匹配效率

内容的提问来源于stack exchange,提问作者sirzento

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 07:36:00