Page 1 of 1

File fingerprinting

Posted: Sun Aug 25, 2024 6:57 am
by Randy Walker
Have fun with it. Improve on it, Steal from it. Do as you wish.
I know its not much but wanted to give back something for all the help I have received: :oops:
; I named the executable "PBfingerprinter" But call it what you want.

Code: Select all

;following code assembled from bits and pieces found
;in help files, on PB forum and some very amateur efforts
;by Randy Walker -- Compiles OK on PB v6.11

UseCRC32Fingerprint()
UseMD5Fingerprint()
UseSHA1Fingerprint()
UseSHA2Fingerprint()
UseSHA3Fingerprint()
Global HWND11
#KB_Escape = #PB_Shortcut_Escape + 49152
#Window_11 = 0
#window_22 = 1
Enumeration
#Text_1_11
#Text_2_11
#Text_3_11
#Manual_11
#More_11
#finger_comment_22
#finger_ClipBrd_22
#finger_Browse_22
#finger_Result_22
#finger_md5_22
#finger_crc_22
#finger_sha1_22
#finger_sha2_22
#finger_sha3_22
#fontAri8
#fontAri8B
#fontAri10B
#fontAri12B
#fontCur12B
EndEnumeration
Debug #fontAri12B
LoadFont(#fontAri8,"Arial",8) 
LoadFont(#fontAri8B,"Arial",8,#PB_Font_Bold)
LoadFont(#fontAri10B,"Arial",8,#PB_Font_Bold)
LoadFont(#fontAri12B,"Arial",12, #PB_Font_Bold)
LoadFont(#fontCur12B,"Courier",12, #PB_Font_Bold)
;LoadFont(#fontCur12B,"Courier",12, #PB_Font_Bold)
StandardFile$ = "C:\XferTemp\"   ; set initial file+path to display 
Pattern$ = "All files (*.*)|*.*" 
Pattern = 0    ; use the first of the three possible patterns as standard 

If OpenWindow(#window_22,0,0,755,80,"",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  ;
  fingername$ = ProgramParameter()
  If fingername$
    fingerUpdate = #True
  EndIf
  ;
  TextGadget(#finger_comment_22, 15, 30,220,20,"")
  SetGadgetFont(#PB_Default,FontID(#fontAri8B))
  ButtonGadget(#finger_ClipBrd_22, 290, 30, 80,20,"` - - > Clipboard")
  ButtonGadget(#finger_Browse_22, 376, 30, 50,20,"Browse")
  SetGadgetFont(#PB_Default,FontID(#fontAri12B))
  ;Next Line Is Output Field
  TextGadget(#finger_Result_22, 8,5,740,20,"Drag a file in here or click Browse" + Result$,#PB_Text_Border)
  SetGadgetFont(#PB_Default,FontID(#fontAri8B))
  OptionGadget(#finger_md5_22,10,53,60,20,"MD5sum")
  OptionGadget(#finger_crc_22,86,53,60,20,"CRC32")
  OptionGadget(#finger_sha1_22,153,53,60,20,"SHA1")
  OptionGadget(#finger_sha2_22,213,53,60,20,"SHA2")
  OptionGadget(#finger_sha3_22,273,53,60,20,"SHA3")
  HideGadget(#finger_ClipBrd_22, 1)
  EnableWindowDrop(#window_22,    #PB_Drop_Files,   #PB_Drag_Copy)
  SetWindowTitle(#window_22, " Fingerprint Calculator")
  SetGadgetText(#finger_comment_22,"    Select the desired fingerprint type below.")
  SetGadgetState(#finger_md5_22, 1)   ; set MD5sum option as active one
  finger.l = #finger_md5_22
  
  HWND22=WindowID(#window_22)
  
  AddKeyboardShortcut(#window_22, #PB_Shortcut_Escape, #KB_Escape)
  
Else
  End
EndIf 
;
  Exe=RunProgram("wmic","cpu get name,currentclockspeed","",#PB_Program_Hide|#PB_Program_Open|#PB_Program_Read|#PB_Program_Error)
  If Exe
    While ProgramRunning(Exe)
      If AvailableProgramOutput(Exe)
        Output$=ReadProgramString(Exe) ;trash first (header) line
        Output$=Left(ReadProgramString(Exe),5) ; Capture 2nd line
        CPU = Val(LTrim(Output$)) ; retain first word only
      EndIf
    Wend
  EndIf
  ;
  Select CPU
    Case 0 To 1600
      size = 200000000
    Case 1601 To 2500
      size = 400000000
    Case 3501 To 5000
      size = 800000000
    Default
      size = 10000000000
  EndSelect
  Repeat
  _mess = WaitWindowEvent()
  ;Debug _mess
  Select _mess
    Case #PB_Event_CloseWindow
      HideWindow(#window_22,1)
    Case #PB_Event_WindowDrop
      Debug "dropped"
      If GetGadgetState(#finger_md5_22) + GetGadgetState(#finger_crc_22) + GetGadgetState(#finger_sha1_22) + GetGadgetState(#finger_sha2_22) + GetGadgetState(#finger_sha3_22)
        Files$ = EventDropFiles()
        fingerName$ = StringField(Files$, 1, Chr(10))
        fingerUpdate = #True
      EndIf
    Case #PB_Event_Gadget
      Select EventGadget()
        Case #finger_ClipBrd_22 ; "Button 1 clicked!"
          Result$ = GetGadgetText(#finger_Result_22)
          SetClipboardText(Trim(Result$))
          Repeat : Until WindowEvent() = 0
        Case #finger_Browse_22 ; "Button 2 clicked!"
          fingerName$ = OpenFileRequester("Please choose file for " + fingerType$ + " test", StandardFile$, Pattern$, Pattern) 
          If fingerName$
            fingerUpdate = #True
          EndIf
        Case #finger_md5_22, #finger_crc_22, #finger_sha1_22, #finger_sha2_22, #finger_sha3_22
          finger.l = EventGadget()
          Debug finger
          Select finger
            Case #finger_md5_22
              fingerType$ = "md5sum"
            Case #finger_crc_22
              fingerType$ = "crc32"
            Case #finger_sha1_22
              fingerType$ = "sha1"
            Case #finger_sha2_22
              fingerType$ = "sha2"
            Case #finger_sha3_22
              fingerType$ = "sha3"
          EndSelect
          If fingerName$
            fingerUpdate = #True
          EndIf
      EndSelect
    Case #PB_Event_Menu
      Select EventMenu()
        Case #KB_Escape
          _mess = #PB_Event_CloseWindow
          ;HideWindow(#window_22,1)
      EndSelect
  EndSelect
  If fingerUpdate = #True
    If FileSize(fingerName$) > size
      Select MessageRequester(" Be Prepared To Wait", "You have selected a very large file for evavluation and this will take time." + Chr(10) + "A 1GB file may take 10 seconds To a Minute depending on" + Chr(10) + "CPU And hard drive performance." + Chr(10) + "" + Chr(10) + "                    Are you prepared To wait For this calculation?", #MB_OKCANCEL)
        Case #IDOK
        Case #IDCANCEL
          fingerUpdate = #False
      EndSelect
    EndIf
    If fingerUpdate = #True
      title$ = GetFilePart(fingerName$)
      SetWindowTitle(#window_22, "  ''"+title$+"'' " + fingerType$ + " value is:")
      Select finger
        Case #finger_md5_22
          Result$ = FileFingerprint(fingerName$,#PB_Cipher_MD5)
        Case #finger_crc_22
          Result$ = FileFingerprint(fingerName$,#PB_Cipher_CRC32)
        Case #finger_sha1_22
          Result$ = FileFingerprint(fingerName$,#PB_Cipher_SHA1)
        Case #finger_sha2_22
          Result$ = FileFingerprint(fingerName$,#PB_Cipher_SHA2)
        Case #finger_sha3_22
          Result$ = FileFingerprint(fingerName$,#PB_Cipher_SHA3)
      EndSelect
      If Result$ = ""
        Result$ = "Unknown error (possibly a locked file)"
      Else
        Result$=UCase(result$)
      EndIf
      StandardFile$ = GetPathPart(fingerName$) + "\"
      HideGadget(#finger_ClipBrd_22, 0)
      SetGadgetText(#finger_comment_22,"Match value above to the documented value.")
      SetGadgetText(#finger_Result_22," " + Result$)
      Debug "Got this far"
      fingerUpdate = #False
    EndIf
  EndIf
Until _mess = #PB_Event_CloseWindow
[EDIT] 08/28/24 -- NEW and improved with big THANKS to HeXOR for the tip that led to the addition of these two lines enabling "SendTo" context menu selection to fingerprint files:

fingername$ = ProgramParameter()
fingerUpdate = #True

[TIP] do Winkey + R and type shell:sendto
Press enter and add a shortcut pointing to your PBfingerprinter program.
Now you can right ckick any file, select [Send To] > [PBfingerprinter]
and get the fingerrprint value for your send to file :)
Very handy if you download a lot of ISO files.

[EDIT] 08/29/24 -- I cleaned up the "Be Prepared To Wait" comment.
[EDIT] 09/12/24 -- "Be prepared to wait" comment augmented by Values determined in the Select CPU section. Maybe someone can suggest better means of adjustment.

[EDIT] 09/17/24 app was opening showing immediate error, so I changed this line:

Code: Select all

  fingerUpdate = #True
TO THIS:

Code: Select all

  If fingername$
    fingerUpdate = #True
  EndIf

Re: File fingerprinting

Posted: Wed Aug 28, 2024 9:44 pm
by Randy Walker
The one thing it is really missing is ability to use in the "sendto" context menu. I know I would have to put a shortcut in the sendto folder but I assume the compiled app would need to be able to accept parameters. I've tested using a shortcut in the sendto folder but does not work from the "sendto" context menu.

[SOLVED] 08/28/24 -- Thanks to HeXOR for his tip about programparameter() I was able to get SendTo working as hoped.

Re: File fingerprinting

Posted: Wed Aug 28, 2024 11:12 pm
by normeus
I set this one for one file to keep it simple, but you can do multiple files and also you might not want to display the GUI if the program is run by sending files to it. to test without creating an EXE go to Compiler->Compiler Options->Compile/run (tab) and add a filename to "Executable Commandline:"

Code: Select all

 If CountProgramParameters()=1  ; if there is one file exactly get the info
   File$ = ProgramParameter()
   path$ = GetPathPart(File$)
   filename$ = GetFilePart(File$)
   comandline=1
EndIf
If File$<>""
   ;load the info into the rest of the program
   
EndIf
If OpenWindow(0, 200, 200, 395, 260, "PureBasic Window", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
   
   
     TextGadget(0,10,10,75,200,"Full Filename")
     StringGadget(1, 85, 10, 225, 25, File$)
     StringGadget(2, 85, 40, 225, 25, path$)
     StringGadget(3, 85, 70, 225, 25, filename$)

  Repeat
    Event = WaitWindowEvent()

    If Event = #PB_Event_CloseWindow  ; If the user has pressed on the close button
      Quit = 1
    EndIf

  Until Quit = 1
  
EndIf

End   ; All the opened windows are closed automatically by PureBasic
norm

Re: File fingerprinting

Posted: Thu Aug 29, 2024 6:25 am
by PBJim
Happy to report that your SHA2 matches an Ubuntu server download, Randy :D

Code: Select all

8762f7e74e4d64d72fceb5f70682e6b069932deedb4949c6975d0f0fe0a91be3 - ubuntu-24.04-live-server-amd64.iso
8762F7E74E4D64D72FCEB5F70682E6B069932DEEDB4949C6975D0F0FE0A91BE3 – Generated by FileFingerprint(fingerName$,#PB_Cipher_SHA2)

Re: File fingerprinting

Posted: Thu Aug 29, 2024 6:26 am
by AZJIO
normeus wrote: Wed Aug 28, 2024 11:12 pm go to Compiler->Compiler Options->Compile/run (tab) and add a filename to "Executable Commandline:"
I didn't know it could be used like that. There were times when I needed this. Testing any tools for PureBasic requires this command line

Protection from wrong choice

Code: Select all

Global StandardFile$
StandardFile$ = GetPathPart(ProgramFilename())    ; set initial file+path to display
; StandardFile$ = GetTemporaryDirectory()    ; set initial file+path to display
; StandardFile$ = GetFilePart(ProgramFilename())    ; set initial file+path to display
; StandardFile$ ="file.iso"    ; set initial file+path to display
; StandardFile$ = ProgramFilename()    ; set initial file+path to display
; StandardFile$ = ""    ; set initial file+path to display

Procedure.s FileSelection()
	ProcedureReturn OpenFileRequester("Please choose file for test", StandardFile$, "All files (*.*)|*.*", 0)
EndProcedure

fingername$ = ProgramParameter()
If Not Asc(fingername$) Or FileSize(fingername$) < 0
	fingerName$ = FileSelection()
	If Not Asc(fingername$) Or FileSize(fingername$) < 0
		End
	EndIf
EndIf
You can write a program something like this. That is, compare two files or an existing hash.

Re: File fingerprinting

Posted: Thu Aug 29, 2024 7:30 am
by Randy Walker
PBJim wrote: Thu Aug 29, 2024 6:25 am Happy to report that your SHA2 matches an Ubuntu server download, Randy :D
That's actually why I created the app to begin with. Downloading CentOS ISOs on a regular basis.

Re: File fingerprinting

Posted: Fri Aug 30, 2024 12:02 am
by Randy Walker
The only remaining thing that bothers me about PBfingerprinter is this simple line:

Code: Select all

If FileSize(fingerName$) > 200000000
It should be regulated by processor speed as well as file size. And maybe also whether the file is onboard SSD or external USB drive, etc, but have no idea how to sample that info from inside PB.

Re: File fingerprinting

Posted: Fri Aug 30, 2024 12:44 am
by Randy Walker
normeus wrote: Wed Aug 28, 2024 11:12 pm google Translate;Makes my jokes fall flat
Oh, but that is funny! :D

Re: File fingerprinting

Posted: Fri Aug 30, 2024 4:05 am
by AZJIO
Randy Walker
Instead of SendTo, you can add an item to the Explorer menu through the registry. Here is a program to add a menu item. I also have a program that adds itself to the registry, or removes it if necessary. Look for the line IsUserAnAdmin_, this is the import code.

Re: File fingerprinting

Posted: Fri Aug 30, 2024 6:17 am
by Randy Walker
AZJIO wrote: Fri Aug 30, 2024 4:05 am Randy Walker
Instead of SendTo, you can add an item to the Explorer menu through the registry.
Can't do it. I never touch my registry unless highly needed AND no other option.

Re: File fingerprinting

Posted: Tue Sep 17, 2024 7:23 am
by Randy Walker
[EDIT] -- -9/16/24 -- changed behavior on Esc key. Formerly would only hide the app window and leave it running in the background, totally undesirable behavior as a standalone. Original code was designed to operate in my main project so hiding the window was appropriate. Now as a standalone in the updated code above, Esc key will close the app.