【.NET】校验文件真实格式

//调用
if (!FileTypeCheck.IsValidFileExtension(file.FileName, uploadFileBytes))
                {
                    //未校验通过时的业务逻辑
                }

//文件校验类


/// <summary>
/// 文件真实格式检查
/// </summary>
public class FileTypeCheck
{
//各文件类型文件头格式成员变量,用于检测文件二进制文件头内容是否合规
    private readonly static Dictionary<string, List<byte[]>> fileSignature = new Dictionary<string, List<byte[]>>
                    {
                    { ".DOC", new List<byte[]> { new byte[] { 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 } } },
                    { ".DOCX", new List<byte[]> { new byte[] { 0x50, 0x4B, 0x03, 0x04 } } },
                    { ".PDF", new List<byte[]> { new byte[] { 0x25, 0x50, 0x44, 0x46 } } },
                    { ".ZIP", new List<byte[]>
                                            {
                                              new byte[] { 0x50, 0x4B, 0x03, 0x04 },
                                              new byte[] { 0x50, 0x4B, 0x4C, 0x49, 0x54, 0x55 },
                                              new byte[] { 0x50, 0x4B, 0x53, 0x70, 0x58 },
                                              new byte[] { 0x50, 0x4B, 0x05, 0x06 },
                                              new byte[] { 0x50, 0x4B, 0x07, 0x08 },
                                              new byte[] { 0x57, 0x69, 0x6E, 0x5A, 0x69, 0x70 }
                                                }
                                            },

                    //图片格式
                    { ".PNG", new List<byte[]> { new byte[] { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A } } },
                    { ".JPG", new List<byte[]>
                                    {
                                              new byte[] { 0xFF, 0xD8, 0xFF, 0xE0 },
                                              new byte[] { 0xFF, 0xD8, 0xFF, 0xE1 },
                                              new byte[] { 0xFF, 0xD8, 0xFF, 0xE8 }
                                    }
                                    },
                    { ".JPEG", new List<byte[]>
                                        {
                                            new byte[] { 0xFF, 0xD8, 0xFF, 0xE0 },
                                            new byte[] { 0xFF, 0xD8, 0xFF, 0xE2 },
                                            new byte[] { 0xFF, 0xD8, 0xFF, 0xE3 }
                                        }
                                        },
                     { ".GIF", new List<byte[]> { new byte[] { 0x47, 0x49, 0x46, 0x38 } } },
                     { ".BMP", new List<byte[]> { new byte[] { 0x42, 0x4D } } },
                     { ".JFIF", new List<byte[]> { new byte[] { 0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46 } } },


                     //视频格式
                     //高清,高占用空间
                    { ".MP4", new List<byte[]> {
                                            new byte[] { 0x00,0x00,0x00,0x18,0x66,0x74,0x79,0x70,0x6D,0x70,0x34,0x32 },
                                            new byte[] { 0x00,0x00,0x00,0x1C,0x66,0x74,0x79,0x70,0x6D,0x70,0x34,0x32 },
                                            new byte[] { 0x00,0x00,0x00,0x20,0x66,0x74,0x79,0x70,0x69,0x73,0x6F, 0x6D },
                                        }
                                        },
                     //高清,中度占用空间
                    { ".MKV", new List<byte[]> {
                                                new byte[] { 0x1A, 0x45, 0xDF, 0xA3, 0xA3, 0x42, 0x86, 0x81, 0x01, 0x42, 0xF7  }
                                            }
                                            },
                    //高清,中度占用空间
                    { ".MOV", new List<byte[]> {
                                                new byte[] { 0x00, 0x00, 0x00, 0x14, 0x66, 0x74, 0x79, 0x70, 0x71, 0x74 }
                                            }
                                            },
                     //高清,低占用空间
                    { ".M4V", new List<byte[]> {
                                                new byte[] { 0x00, 0x00, 0x00, 0x20, 0x66, 0x74, 0x79, 0x70, 0x4D, 0x34, 0x56 }
                                            }
                                            },
                    //高清,低占用空间
                    { ".WEBM", new List<byte[]> {
                                                new byte[] { 0x1A, 0x45, 0xDF, 0xA3, 0x9F, 0x42, 0x86, 0x81, 0x01, 0x42, 0xF7, 0x81, 0x01, 0x42, 0xF2 }
                                            }
                                            },
                      //低质量
                     { ".WMV", new List<byte[]> {
                                                  new byte[] { 0x30,0x26,0xB2,0x75,0x8E,0x66,0xCF,0x11}
                                            }
                                            },
                        //低质量
                       { ".AVI", new List<byte[]> {
                                              new byte[] { 0x52, 0x49, 0x46, 0x46, 0x84, 0x4A, 0x1E, 0x00, 0x41, 0x56, 0x49 }
                                            }
                                            },
                         //低质量
                       { ".FLV", new List<byte[]> {
                                              new byte[] { 0x46, 0x4C, 0x56 }
                                            }
                                            },


                    //电子表格
                    { ".XLS", new List<byte[]>
                                            {
                                              new byte[] { 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 },
                                              new byte[] { 0x09, 0x08, 0x10, 0x00, 0x00, 0x06, 0x05, 0x00 },
                                              new byte[] { 0xFD, 0xFF, 0xFF, 0xFF }
                                            }
                                            },
                    { ".XLSX", new List<byte[]> { new byte[] { 0x50, 0x4B, 0x03, 0x04 } } },
                    { ".PPT", new List<byte[]> { new byte[] { 0xd0, 0xCF, 0x11, 0xE0, 0xa1, 0xb1, 0x1a, 0xe1 } } },
                    { ".PPTX", new List<byte[]> { new byte[] { 0x50, 0x4B, 0x03, 0x04, 0x14, 0x00, 0x06, 0x00 } } },
                };

    /// <summary>
    /// 文件真实格式检查
    /// </summary>
    /// <param name="fileName">文件名,包含后缀</param>
    /// <param name="fileData">文件数据</param>
    /// <param name="allowedChars">允许的例外字节数组</param>
    /// <returns></returns>
    public static bool IsValidFileExtension(string fileName, byte[] fileData, byte[] allowedChars = null)
    {
        if (string.IsNullOrEmpty(fileName) || fileData == null || fileData.Length == 0)
        {
            return false;
        }
        bool flag = false;
        string ext = System.IO.Path.GetExtension(fileName);
        if (string.IsNullOrEmpty(ext))
        {
            return false;
        }
        ext = ext.ToUpperInvariant();

        //if (ext.Equals(".TXT") || ext.Equals(".CSV") || ext.Equals(".PRN"))
        //{
        //    foreach (byte b in fileData)
        //    {
        //        if (b > 0x7F)
        //        {
        //            if (allowedChars != null)
        //            {
        //                if (!allowedChars.Contains(b))
        //                {
        //                    return false;
        //                }
        //            }
        //            else
        //            {
        //                return false;
        //            }
        //        }
        //    }
        //    return true;
        //}

        //if (!fileSignature.ContainsKey(ext))
        //{
        //    return true;
        //}
        if (".TXT".Equals(ext) || ext.Equals(".CSV") || ext.Equals(".PRN")) {
            return true;
        }
        //通过文件后缀获取该类文件文件头List
        List<byte[]> sig = fileSignature[ext];
        //循环判断
        foreach (byte[] b in sig)
        {
            //创建与当前循环内容长度相等的字节数组
            var curFileSig = new byte[b.Length];
            //拷贝与当前循环内容长度相等的文件字节内容至curFileSig
            Array.Copy(fileData, curFileSig, b.Length);
            if (curFileSig.SequenceEqual(b))
            {//判断curFileSig与当前循环内容是否一致,一致则验证通过
                //验证格式通过
                flag = true;
                break;
            }
        }
        return flag;
    }

}

补充:如何获取文件二进制内容

使用Notepad++打开任意文件

打开后会显示乱码,按照图示红框打开插件16进制编辑器,如没有点击插件管理安装

点击16进制编辑器后会显示文件16进制编码,在00000000地址处截取开头部分内容及为该类型文件头(PS:可更具实际需求截取相应要求的长度进行校验,注意不要截取过长导致截取到文件内容部分)

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值