WinFuture-Forum.de: Sha1-prüfsummen Berechnen - WinFuture-Forum.de

Zum Inhalt wechseln

Nachrichten zum Thema: Entwicklung
Seite 1 von 1

Sha1-prüfsummen Berechnen ein paar kleine Details


#1 Mitglied ist offline   Rika 

  • Gruppe: aktive Mitglieder
  • Beiträge: 11.533
  • Beigetreten: 11. Juni 03
  • Reputation: 2
  • Geschlecht:Männlich

geschrieben 19. Dezember 2006 - 10:30

Ich hab jetzt folgendes Script, um SHA1-Prüfsummen von Dateien zu berechnen, in einem Alternate Data Stream namens "SHA1" dauerhaft zu speichern, wieder auszulesen, zu vergleichen und damit Duplikate zu elimieren. Ziel ist gegenüber der vorherigen Version, daß auch bei vielen Dateien unnötige Prozesserzeugungen vermieden werden.

@echo off
set tmp1=%temp%\%random%%random%%random%%random%.tmp
set tmp2=%temp%\%random%%random%%random%%random%.tmp
set tmp3=%temp%\%random%%random%%random%%random%.tmp
if "%1"=="-c" (
	call :find_files_withhashes !tmp1!
	if exist !tmp1! (
		dir /s /b /a-d>!tmp2!
		echo Missing:
		if exist !tmp2! (
			cat !tmp1! !tmp2! | sort | uniq -u
			del !tmp2!
		)
		call :retrieve_hashes !tmp1! !tmp2!
		call :calculate_hashes !tmp1! !tmp3!
		del !tmp1!
		echo.
		echo Inconsistent:
		cat !tmp2! !tmp3! | sort | uniq -u
		del !tmp2! !tmp3!
	) ELSE (
		echo Missing:
		dir /s /b /a-d
	)
)
if "%1"=="-u" (
	call :calculate_hashes 'dir/s/b/a-d' !tmp1!
	if exist !tmp1! (
		call :write_hashes_to_files !tmp1!
		del !tmp1!
	)
)
if "%1"=="-e" (
	call :find_files_withhashes !tmp1!
	if exist !tmp1! (
		call :retrieve_hashes !tmp1! !tmp2!
		type !tmp2!
		del !tmp1! !tmp2!
	)
)
if "%1"=="-l" (
	call :find_files_withhashes !tmp1!
	if exist !tmp1! (
		call :retrieve_hashes !tmp1! !tmp2!
		set x=
		for /f "delims=" %%i in (!tmp2!) do (
			set x=%%i
			set file=!x:~42!
			for %%j in ("!file!") do echo !x:~0,40!;!file!;%%~zj 
		)
		del !tmp1! !tmp2!
	)
)
if "%1"=="-a" (
	dir /s /b /a-d>!tmp1!
	call :find_files_withhashes !tmp2!
	if exist !tmp2! (
		cat !tmp1! !tmp2! | sort | uniq -u>!tmp3!
		cat <!tmp3! >!tmp1!
		del !tmp2! !tmp3!
	)
	call :calculate_hashes !tmp1! !tmp2!
	del !tmp1!
	if exist !tmp2! (
		call :write_hashes_to_files !tmp2!
		del !tmp2!
	)
)
if "%1"=="-d" (
	call :find_files_withhashes !tmp1!
	if exist !tmp1! (
		call :retrieve_hashes !tmp1! !tmp2!
		set x=
		for /f "delims=" %%i in ('sort /r ^<!tmp2! ^| uniq -w 40 -d') do (
			set x=%%i
			echo !x:~42!
		)
		del !tmp1! !tmp2!
	)
)
@echo on
@goto :eof

:find_files_withhashes %1
rem	@return	%1	list of files which have hashes
set x=
for /f "delims=" %%i in ('lads . /s ^| find /i ":sha1"') do (
	set x=%%i
	echo !x:~12,-5!>>%1
)
goto :eof

:retrieve_hashes %1 %2
rem	@filelist	%1	list of files which have hashes
rem	@return		%2	list of files with their hashes (hash<space><space>filename)
for /f "delims=" %%i in (%1) do (
	 for /f "usebackq delims=" %%j in ("%%~i:SHA1") do (
		echo %%j  %%~i>>%2
	 )
)
goto :eof

:calculate_hashes %1 %2
rem	@filelist	%1	list of files whichs hashes should be calculated
rem	@return		%2	list of files with their hashes (hash<space><space>filename)
set filelist=
set counter=0
for /f "delims=" %%i in (%1) do (
	set filelist=!filelist! "%%~i"
	set /a counter+=1
	if /i !counter! GEQ 126 (
		set counter=0
		if NOT "!filelist!"=="" (
			sha1sum !filelist!>>%2
			set filelist=
		)
	)
)
if NOT "!filelist!"=="" (
	sha1sum !filelist!>>%2
)
goto :eof

:write_hashes_to_files %1
rem	@filelist	%1	list of files with their hashes (hash<space><space>filename)
set x=
for /f "delims=" %%i in (%1) do (
	set x=%%i
	echo !x:~0,40!>"!x:~42!":SHA1
)
goto :eof


Meine Fragen:
1. Sieht jemand eine gute Möglichkeiten, bei mehrfachem Aufruf mit verschiedenen Parametern (klassische Fälle sind (a)dd+(d)uplicate und (a)dd+(l)ist) die Zwischendateien sinnvoll zu recyclen?
2. "sha1sum" erwartet eine Liste von Dateien, diese ist aber durch die Variablengröße beschränkt. Weiß einer, wie man da sinnvoll eine maximale Auslastung erreichen kann? Derzeit hab ich's auch 126*256<32K beschränkt, aber das wird praktisch nie ausgenutzt. Wie kann man sinnvoll die Länge des Inhaltes einer Variablen ermitteln?
3. Kann man auch ohne das FOR-Konstrukt die Dateilänge zu einer Datei ermitteln?
4. Was ich mich schon lange frage: Wie kann ich '!' und '^' in Dateinamen escapen?
5. Sieht irgendwer Fehler, Mängel oder hat gute Ideen für Erweiterungen?
Konnichiwa. Manga wo shitte masu ka? Iie? Gomenne, sonoyouna koto ga tabitabi arimasu. Mangaka ojousan nihongo doujinshi desu wa 'Clamp X', 'Ayashi no Ceres', 'Card Captor Sakura', 'Tsubasa', 'Chobits', 'Sakura Taisen', 'Inuyasha' wo 'Ah! Megamisama'. Hai, mangaka gozaimashita desu ni yuujin yori.
Eingefügtes Bild
Ja, mata ne!

(For sending email please use OpenPGP encryption and signing. KeyID: 0xA0E28D18)
0

Anzeige



#2 Mitglied ist offline   Graumagier 

  • Gruppe: aktive Mitglieder
  • Beiträge: 8.811
  • Beigetreten: 01. März 04
  • Reputation: 1
  • Geschlecht:Männlich
  • Wohnort:Graz, Österreich

geschrieben 19. Dezember 2006 - 10:57

Rika sagte:

3. Kann man auch ohne das FOR-Konstrukt die Dateilänge zu einer Datei ermitteln?

dir + Spalte umleiten? Geht sowas unter Windows? Gerade keine Möglichkeit das zu testen...
"If you make something idiot proof, someone will invent a better idiot." - Marvin

For Emails always use OpenPGP. My KeyID: 0xA1E011A4
0

#3 Mitglied ist offline   Witi 

  • Gruppe: aktive Mitglieder
  • Beiträge: 5.942
  • Beigetreten: 13. Dezember 04
  • Reputation: 43
  • Geschlecht:Männlich
  • Wohnort:Kingsvillage
  • Interessen:Frickeln

geschrieben 19. Dezember 2006 - 11:15

Zitat

dir + Spalte umleiten?

Das ist auch das erste was mir eingefallen ist. Afaik lässt sich das aber auch nur über ein FOR-Konstrukt lösen.

Ich glaube niemand aus dem Forum hat dieses tiefe Wissen, um dir zu den restlichen Fragen irgendeine Antwort geben. Wäre jedoch schon, wenn doch :veryangry:

Zitat

5. Sieht irgendwer Fehler, Mängel oder hat gute Ideen für Erweiterungen?

Was mir beim Überfliegen des Codes aufgefallen ist, dass du Unixbefehle benutzt (Wahrscheinlich cygwin).
cat kannst du bspw durch type ersetzen, aber uniq ist leider wirklich unique unter Unix (5 Euro ins Phrasenschwein...).
0

#4 Mitglied ist offline   Graumagier 

  • Gruppe: aktive Mitglieder
  • Beiträge: 8.811
  • Beigetreten: 01. März 04
  • Reputation: 1
  • Geschlecht:Männlich
  • Wohnort:Graz, Österreich

geschrieben 19. Dezember 2006 - 11:45

Witi sagte:

Afaik lässt sich das aber auch nur über ein FOR-Konstrukt lösen.

Na das schon. Müsste man testen welche Lösung performanter ist (so die dir-Lösung möglich ist). Unter Monad wär's wohl weniger problematisch.
"If you make something idiot proof, someone will invent a better idiot." - Marvin

For Emails always use OpenPGP. My KeyID: 0xA1E011A4
0

#5 Mitglied ist offline   Rika 

  • Gruppe: aktive Mitglieder
  • Beiträge: 11.533
  • Beigetreten: 11. Juni 03
  • Reputation: 2
  • Geschlecht:Männlich

geschrieben 19. Dezember 2006 - 12:16

Zitat

dir + Spalte umleiten?

Ja toll, dann wird pro Datei noch ein neuer Prozess gestartet...

Mit dem Expandieren mit %~z geht das auch einfach so. Leider macht er das nur mit den Variablen der FOR-Schleife sowie Call-Argumenten, aber nicht mit direkten Variablen. Deshalb ja der Workaround. Es ist nicht inperformant, sondern nur etwas umständlich.

Moment mal... man könnte doch einfach %%i zurückzuweisen und dann expandieren. Gleich mal probieren...

Und wenn man alle Dateien auf einmal'dir't, die Dateigröße zusammensucht und auf die Dateien die jeweiligen Dateien matcht, dann ist das erst recht umständlich.

Zitat

cat kannst du bspw durch type ersetzen

Hey, mit 'type' kann man ja auch Dateien konkatentieren. Aber leider werden dann die Dateinamen eingestreut. Also bleiben wir doch lieber bei 'cat'.

Zitat

aber uniq ist leider wirklich unique unter Unix (5 Euro ins Phrasenschwein...).

sha1sum auch. Und die braucht man auf jeden Fall. Und nein, statt Cygwin nehmen man die UnxUtils oder GnuWin32.
EDIT: Oder sollte man Uniq lieber durch ein eigenes Konstrukt mit FOR-Schleife ersetzen?



Ach ja: Ihr könnt das Script natürlich frei verwenden.

Dieser Beitrag wurde von Rika bearbeitet: 19. Dezember 2006 - 13:20

Konnichiwa. Manga wo shitte masu ka? Iie? Gomenne, sonoyouna koto ga tabitabi arimasu. Mangaka ojousan nihongo doujinshi desu wa 'Clamp X', 'Ayashi no Ceres', 'Card Captor Sakura', 'Tsubasa', 'Chobits', 'Sakura Taisen', 'Inuyasha' wo 'Ah! Megamisama'. Hai, mangaka gozaimashita desu ni yuujin yori.
Eingefügtes Bild
Ja, mata ne!

(For sending email please use OpenPGP encryption and signing. KeyID: 0xA0E28D18)
0

Thema verteilen:


Seite 1 von 1

1 Besucher lesen dieses Thema
Mitglieder: 0, Gäste: 1, unsichtbare Mitglieder: 0