File Signature


هذا الموضوع الهدف منه توضيح ماهية File Signature الخاصة بجميع الملفات الشهيرة و المعروفة لنظام التشغيل في جهاز الكمبيوتر

ماذا تعني كلمة File Signature 

هو عبارة عن خليط من حروف و أرقام يتم إضافتها في بداية الملف ومن خلاله تستطيع تحديد هوية الملف و هذا الخليط من الحروف و الأرقام يعمل بمثابة ختم أو Stamp للملف ومنه يستطيع نظام التشغيل Operating System الموجود علي جهاز الكمبيوتر الخاص بك تحديد نوعية البرنامج الذي يصلح لفتح الملف

بشكل عام هذا الخليط من الأرقام و الحروف يتم كتابته الي الملف علي هيئة بايت  Byte أيضا هذا الخليط غالبا له قيمة ثابتة و في بعض الأحيان تقوم الشركات بتغيير قيمة هذا الخليط طبقا لإحتياجاتها وأيضا كل شركة شهيرة من شركات الكمبيوتر تستخدم قيمة خاصة بها حسب نوعية الملفات

وكمثال توضيحي للفكرة لنفترض أنك قمت بتشغيل برنامج Paint ثم فتحت ملف جديد من خلال البرنامج و سواء رسمت أو لم ترسم شيئا في الملف ثم قمت بحفظ الملف هنا يقوم برنامج Paint بإضافة قيمة  معينة وهذه القيمة ممثلة في الحرفان BM ويتم اضافة هذان الحرفان في بداية الملف بحيث يعمل هذان الحرفان بمثابة التوقيع لهذا الملف و يحلو للبعض أن يطلق علي هذه القيمة اسم File Signature و البعض الأخر يحلو له أن يطلق عليها الإسم Magic Number أيضا هناك بعض الشركات قد تضيف هذه القيمة إما في نفس الملف أو تضيفها في ملف أخر منفصل
 
و لكي تتأكد مما أقول حاول أن تفتح أي ملف يكون امتداه BMP بأي برنامج Hex Editor وحينها ستري شئ مشابه للصورة الموجودة أدناه

ما هي فوائد File Signature 

من خلاله يتم تحديد نوع الملف حتي و إن كان الملف لم يكن له أي امتداد


من خلاله يتم تحديد نوع البرنامج الذي يصلح لفتح الملف

من خلاله يتم ربط البرنامج مع الملفات التي لها نفس الامتداد وهذا الامر مفيد في عمل امتداد خاص ببرنامجك

من خلاله قد تستطيع من تحديد معرفة اسم الشركة المنتجة للملف

طبعا ربما هناك فوائد أخري و الأمر هنا متروك لمخيلة القارئ للتفكير في فوائد أخري أو التفكير في كيفية اإستفادة من هذا الموضوع في برامجه الخاصة.


الكود
 

كمثال لنأخذ الملفات التي من النوع PDF وهي ملفات شهيرة و معروفة للجميع و قيم File Signature الخاص بهذا النوع من الملفات تم أخذها من أحد المواقع الشهيرة علي النت و هو موقع WIKI و تم كتابة البيانات علي هيئة كود من اجل التوضيح فقط


    Dim pdf_Extension As String "pdf"
 
       Dim pdf_Description As String "PDF document"
 
       Dim pdf_Offset As Integer 0
        Dim pdf_Ascii 
As String "%PDF"
 
       Dim pdf_HeStrings As String "25 50 44 46"


بشكل عام لو حاولت تحويل المتغير pdf_Ascii  من String الي HexString ستجد أن الناتج يساوي قيمة المتغير pdf_HexString  والكود التالي يوضح ذلك

   Dim sb As New System.Text.StringBuilder
        For Each c 
As Char In pdf_Ascii
            sb
.AppendFormat(System.Globalization.CultureInfo.InvariantCulture"{0:X} "Convert.ToByte(c))
 
       Next

        Me
.Text sb.ToString 


عموما يجب أن لا تعتمد كثيرا علي هذا الأسلوب في تحويل البيانات لأننا ستكتشف ان بعض الملفات قد لا تلتزم بنفس منهج تحويل المتغيرات عند كتابة File Signature الي الملف كمثال علي ذلك الملفات من النوع PNG



  Dim png_Extension As String "png"
 
       Dim png_Description As String "Image encoded in the Portable Network Graphics format"
 
       Dim png_Offset As Integer 0
        Dim png_Ascii 
As String ".PNG...."
 
       Dim png_HeStrings As String "89 50 4E 47 0D 0A 1A 0A"


 
       Dim sb As New System.Text.StringBuilder
        For Each c 
As Char In png_Ascii
            sb
.AppendFormat(System.Globalization.CultureInfo.InvariantCulture"{0:X} "Convert.ToByte(c))
 
       Next

        Me
.Text sb.ToString


لذلك لا تنخدع أو لا تتسرع و تقوم بتحويل البيانات عن طريق كتابة دالة  لتحويل الحروف التي تخص File Signature ASCII الي Hex String لأنك قد تحصل علي شئ مختلف أحيانا


ملحوظة هامة

هناك حالات قد تجد أكثر من قيمة لنفس النوع من الملفات علي سبيل المثال الملفات من النوع CAB لها قيمتان و أيضا الملفات من النوع GIF لها قيمتان أيضا

مثلا الملفات التي إمتدادها ينتهي بالحروف CAB والخاصة بشركة مايكروسوفت سنجد أن قيمة File Signature الخاص بها كالتالي


      Dim cab_MS_Extension As String "cab"
 
       Dim cab_MS_Description As String "Microsoft cabinet file"
 
       Dim cab_MS_Offset As Integer 0
        Dim cab_MS_Ascii 
As String "MSCF"
 
       Dim cab_MS_HeStrings As String "4D 53 43 46"


بينما نفس الملفات و التي هي من انتاج البرنامج الشهير Install Shield سنجد أن القيمة لها كالتالي


 Dim cab_InstallShield_Extension As String "cab"
 
       Dim cab_InstallShield_Description As String "Install Shield compressed file"
 
       Dim cab_InstallShield_Offset As Integer 0
        Dim cab_InstallShield_Ascii 
As String "ISc("
 
       Dim cab_InstallShield_HeStrings As String "49 53 63 28"

مثال أخر الملفات من النوع GIF لها قيمتان القيمة الأولي كالتالي

      Dim gif87a_Extension As String "gif"
 
       Dim gif87a_Description As String "Image file encoded in the Graphics Interchange Format"
 
       Dim gif87a_Offset As Integer 0
        Dim gif87a_Ascii 
As String "GIF87a"
 
       Dim gif87a_HeStrings As String "47 49 46 38 37 61"

والقيمة الثانية للملفات من النوع GIF كالتالي

 Dim gif89a_Extension As String "gif"
 
       Dim gif89a_Description As String "Image file encoded in the Graphics Interchange Format"
 
       Dim gif89a_Offset As Integer 0
        Dim gif89a_Ascii 
As String "GIF89a"

لذلك وعند التأكد  من File Signature الخاص بالملفات والتي لها أكثر من Signature يجب علينا دائما أن نتأكد من جميع القيم كما في حالة الملفات التي لها امتداد GIF يجب هنا ان نتأكد من القيمتان معا

مثال أخر الملفات المضغوطة من النوع RAR لها قيمتان أحدهما تعبر عن الملفات من النسخة Version 1.5 حتي النسخة Version 5  من نفس البرنامج ثم من النسخة Version 5 فيما فوق لها رقم اخر

للأسف وكما تلاحظون أن File Signature هذا غير ثابتة القيمة وقد يتم تغيير تلك القيمة لأي أسباب بواسطة الشركات المنتجة للملفات لذلك و عند التأكد من قيمة File Signature يجب دوما ان نراعي اي تعديلات تقوم بها الشركات المختلفة

كيف نقرأ قيمة File Signature

الخطوات التالية توضح الكيفية

أولا: نحتاج الي حفظ جميع المعلومات عن الملف علي هيئة داتا بيز وهذه المعلومات يتم تجميعها من المواقع المختلفة علي النت أو بأي صورة تجدها مناسبة لك و ما يهمني هنا من تلك البيانات التي يتم تجميعها هي قيمة المتغير HexString الخاصة بكل نوع من الملفات

ثانيا: نقوم بتحويل البيانات الخاصة بالمتغير HexString الي مصفوفة Byte

ثالثا: نقوم بقراءة الملف المطلوب التاكد من Signature الخاص به الي Stream

رابعا: نقوم بقراءة Header الخاص بالملف وهو هنا عبارة عن مصفوفة من Byte

خامسا: نقارن بين تلك القيمة التي نقرأها من File  Header  مع قيمتها الموجودة في الداتا بيز الخاصة بالملفات فإن تساوت القيمتان هنا نستطيع تحديد نوع الملف

طبعا الكلام النظري قد يكون غير مفهوم قليلا للبعض لذلك لنقوم بصياغته بشكل عملي و تحويله الي أكواد و سنأخذ الملفات من النوع PDF كمثال


المرحلة الأولي
        ' 
تجميع المعلوامت و البيانات الخاصة بالملف
        
' ------------------------------------------------تحميع المعلومات عن الملف-----------------------------------
        ' 
Adobe PDF File datacollected form WIKI site
        Dim pdf_Extension 
As String "pdf"
 
       Dim pdf_Description As String "PDF document"
 
       Dim pdf_publisher As String "Adobe"
 
       Dim pdf_Offset As Integer 0
        Dim pdf_Ascii 
As String "%PDF"

 
       ' PDF file signature string
        Dim pdf_Sig As String = "25 50 44 46"

        ' 
convert PDF File Signature string to hex values
        Dim pdf_hexValues 
As Integer() = New Integer() {&H25, &H50, &H44, &H46}


 
       ' المرحلة الثانية
        ' 
---------------------------------------------------Cnvert PDF File hex values to bytes-------------------------
 
       ' هذا هو الجزء الذي يهمنا جدا معرفته عن الملف
        Dim pdf_bytes As Byte() = New Byte() {37, 80, 68, 70}

        ' 
المرحلة الثالثة
        
' ------------------------------ تعريف و قراءة الملف الموجود علي الكمبيوتر ------------------------------------
        ' 
define the location of PDF File
        
' تم اضافة الملف لفهرس المشروع للإختبار فقط لا غير
        Dim filePath As String = ".\Chart.pdf"
        ' 
convert the PDF file to stream
        Dim dataStream 
As New IO.FileStream(filePathIO.FileMode.OpenIO.FileAccess.ReadIO.FileShare.Read)

 
       ' المرحلة الرابعة
        ' 
----------------------------------------Read File Header--------------------------------------------------------
 
       Dim capacity As Integer 8
        Dim bytes 
As Byte() = New Byte(capacity 1) {}
 
       Dim position As Long dataStream.Position
        dataStream
.Seek(0IO.SeekOrigin.Begin)
 
       Dim i As Integer 0
        While i 
capacity
            pdf_Offset 
dataStream.Read(bytespdf_Offsetcapacity i)
 
           If pdf_Offset <= 0 Then
                Exit 
While
 
           End If
 
           i += pdf_Offset
        End 
While

 
       ' المرحلة الخامسة
        '
----------------------------- مقارنة المصفوفات ------------------------------------------------------------------
 
       ' compare byte arrays
        Dim isEqualSig As Boolean = True
        If bytes.Length < pdf_bytes.Length Then
            isEqualSig = False
        End If
        For j As Integer = 0 To pdf_bytes.Length - 1
            If bytes(j) <> pdf_bytes(j) Then
                isEqualSig = False
            End If
        Next


        ' 
المرحلة الأخيرة  التأكد من النتائج
        
' -----------------------------------------------------------------------------------------------------------------
        ' 
لو كانت المصفوفتان متساويتان
        If isEqualSig Then
            
' do something
            MessageBox.Show(" The File is Adobe PDF File", "Info")
        Else
            ' 
do something
            MessageBox
.Show(" The File is NOT Adobe PDF File""Info")
 
       End If

بالطبع و من الأفضل تحويل الكود أعلاه الي كلاسات تحتوي علي دوال و اجراءات حتي نستطيع التعامل مع جميع الملفات المعروفة
   
كمثال الكود التالي يوضح شكل الدالة التي من الممكن استخدامها لتحويل بعض البيانات من مصفوفة من النوع Integer الي مصفوفة من النوع Byte 



Private Function ToBytes(hexValues As Integer()) As Byte()
 
       Dim bytes As List(Of Byte) = New List(Of Byte)()
 
       For Each i As Integer In hexValues
            bytes
.Add(System.Convert.ToByte(i))
 
       Next
        Return bytes
.ToArray
    End 
Function

مثال أخر الكود التالي يوضح شكل الدالة التي من الممكن استخدامها لقراءة الملف المراد تحديد File Signature الخاص به و تحويله الي Stream 

Public Function FileToStream(filePath As String) As IO.FileStream
        Dim result 
As IO.FileStream Nothing
        Try
            result 
= New IO.FileStream(filePathIO.FileMode.OpenIO.FileAccess.ReadIO.FileShare.Read)
 
       Catch ex As Exception
        End 
Try
 
       Return result
    End 
Function 


مثال أخر الكود التالي يوضح شكل الدالة التي من الممكن استخدامها للمقارنة بين مصفوفة File Signature والمصفوفة التي نقرأهت من File Header الخاصة بالملف

 ''' 



    ''' 
compare signature
    
''' 

    ''' <param name="leftSig">represents the file header byte array</param>
 
   ''' represent the file signature byte array collected from internet
    ''' 
<returns></returns>
 
   Public Function IsSignaturesAreEqual(leftSig As Byte(), rightSig As Byte()) As Boolean
        If leftSig
.Length rightSig.Length Then
            Return False
        End 
If
 
       For i As Integer 0 To rightSig.Length 1
            If leftSig
(i) <> rightSig(iThen
                Return False
            End 
If
 
       Next
        Return True
 

    End Function

 لمزيد من التفاصيل عن File Signature يمكنكم زيارة الروابط التالية و الاستفادة من المعلومات الموجودة بها


Download



Comments

Popular posts from this blog

مقدمة الي تشفير الحروف الأبجدية العربية

VB.NET Translucent Control using GDI+

Add Custom Event to a Class in VB.NET