Page 1 sur 1

fciv et chcp ?

Posté : jeu. 18 juil. 2019 08:59
par papami
Bonjour,
à l'aide :)

avec ce code
$f="C:\test\essai2.txt"
$hash = Run ( @ComSpec & " /c fciv -add " & '"' & $f & '"' & " -md5", @TempDir, @SW_HIDE, $STDOUT_CHILD )
ProcessWaitClose ( $hash )
$hashstring = StdoutRead ( $hash )
msgbox (0,"Hash","MD5=" & '"' & $hashstring & '"')
le résultat est correct
mais si le fichier s'appelle pépé.txt il y a erreur (comme pour tout autre caractère accentué)

comment paramétrer (envoyer chcp ...) pour résoudre le problème ?

Merci beaucoup

Re: fciv et chcp ?

Posté : jeu. 18 juil. 2019 12:03
par jchd
Il y a pire : si le nom de fichier contient des caractères Unicode > 0x100, fciv ne le traite pas du tout ! Il n'est pas non plus spécialement véloce sur les gros fichiers et le format de stockage n'est pas formidable.

A votre place, je ferais le(s) hash(es) moi-même et je les stockerais à ma façon. Ma façon c'est forcément une base de données SQLite, ça va sans dire !
Voici un squelette de pseudo code :

Code : Tout sélectionner

#include <SQLite.au3>

_SQLite_Startup()
_SQLite_Open("MonRépertoire\Hashes.sq3) ; open Database
_SQLite_Exec(-1, "CREATE TABLE if not exists Hashes (Id integer primary key, Date char, Chemin char, Fichier char, MD5 char, SHA1 char);" & _
				"create index if not exists IdxCheminComplet on Hashes (Chemin, Fichier);" & _
				"create index if not exists IdxFichier on Hashes (Fichier);" _
			)
_FileListToArrayRec()
Local $md5, $sha1, $fullpath, $chemin, $fichier
For fichier In list
	_PathFull()		; optionnel
	_PathSplit()	; -> chemin, fichier
	$md5 = _md5forfile($fullpath)
	$sha1 = _sha1forfile($fullpath)
	_SQLite_QuerySingleRow(..., $fullpath, ...)
	If old_md5 <> $md5 or old_SHA1 <> $sha1 Then
		Disp("Le fichier ... a changé ...")
		...
	Else
		Disp("Nouveau fichier ...")
		_SQLite_Exec(-1, "insert into hashes (Date, Chemin, Fichier, MD5, SHA1) " & _
						 "values (datetime, " & esc($chemin) & ", " & esc($fichier), ", " & $md5 & ", " & $sha1 & ";)" _
					)
	EndIf
Next
_SQLite_Close()
_SQLite_Shutdown()
Voir ce fil : https://www.autoitscript.com/forum/topi ... for-files/
Il serait même souhaitable de chiffer cette BdD, ce qui est très simple. Il suffit d'utiliser System.Data.SQLite.dll au lieu de sqlite.dll et d'ajouter deux lignes de code :

Code : Tout sélectionner

_SQLite_Startup()
_SQLite_Open("MonRépertoire\Hashes.sq3) ; open Database
Local $key = InputBox("Contrôle d'accès", "Entrer la clé de chiffrement", "", "*", ...)	; saisie de la clé
_SQLite_Exec(-1, "pragma key = " & esc($key) & ";")	; permet la lecture d'une base chiffrée
Pour le chiffrement initial, changer la clé ou annuler le chiffrement : _SQLite_Exec(-1, "pragma rekey = " & esc($newkey) & ";")
Par contre, avant de changer la clé d'un chiffrement en place, il faut bien sûr fournir l'ancienne clé. Si la clé est perdue, la base devient illisible (c'est le but !).
On dispose aussi de :
pragma hexkey = '012345ABCD'
pragma hexrekey = '012345ABCD'
pour indiquer une clé en format binaire.

https://system.data.sqlite.org/index.ht ... loads.wiki

Si vous tenez absolument à utuliser fciv, le plus simple est de faire une conversion de l'encodage du résultat.

Code : Tout sélectionner

Func _CodepageToString($sCP, $iCodepage = Default)
	If $iCodepage = Int(RegRead("HKLM\SYSTEM\CurrentControlSet\Control\Nls\Codepage", "OEMCP"))
	Local $tText = DllStructCreate("byte[" & StringLen($sCP) & "]")
	DllStructSetData($tText, 1, $sCP)
	Local $aResult = DllCall("kernel32.dll", "int", "MultiByteToWideChar", "uint", $iCodepage, "dword", 0, "struct*", $tText, "int", StringLen($sCP), _
			"ptr", 0, "int", 0)
	Local $tWstr = DllStructCreate("wchar[" & $aResult[0] & "]")
	$aResult = DllCall("kernel32.dll", "int", "MultiByteToWideChar", "uint", $iCodepage, "dword", 0, "struct*", $tText, "int", StringLen($sCP), _
			"struct*", $tWstr, "int", $aResult[0])
	Return DllStructGetData($tWstr, 1)
EndFunc   ;==>_CodepageToString

Re: fciv et chcp ?

Posté : jeu. 18 juil. 2019 17:19
par Tlem
Bonjour.
Pour contourner le problème de caractères accentués, renommez simplement le fichier avec un nom temporaire qui conviendra à fciv, ou si le fichier est de petite taille faites en une copie dans un dossier temporaire. ^^

Il existe d'autres solutions :
  • Pure AutoIt. Mais ne comptez pas sur la performance.

  • AutoIt + Dll (il me semble avoir vu ça sur le forum US).

  • Outil de calcul compatible avec les accents (md5sums.exe par exemple).

  • Ligne de commande Powershell (Powershell get-filehash File2Test.exe -algorithm MD5)

  • VBscript.

  • Et il existe très surement d'autres solutions.
Après quelques tests, la solution fciv est vraiment la plus rapide sur de gros fichiers. 22s pour un fichier de 6 Go alors que PowerShell mets 30 s et md5sums.exe mets 40 s.
Je n'ai pas testé les solutions AutoIt car je sais d'office que les temps seront plus élevés. Mais si vos fichiers ont une taille raisonnable (quelque Mo tout au plus) et que vous n'avez pas plusieurs dizaines de fichiers à tester, alors la solution pure AutoIt est pour vous.

Re: fciv et chcp ?

Posté : jeu. 18 juil. 2019 17:30
par papami
Bonjour,
et merci.
je vais essayer ...

Re: fciv et chcp ?

Posté : jeu. 18 juil. 2019 17:40
par Tlem
Une autre solution que j'ai oublié de vous indiquer, consiste à utiliser le nom court des fichiers (le nom 8.1). ^^

Re: fciv et chcp ?

Posté : jeu. 18 juil. 2019 17:53
par papami
ah ben ça c'est peut-être une bonne idée :)

toutefois si FCIV traite bien les fichiers avec caractères accentués dans le texte.

re-merci

Re: fciv et chcp ?

Posté : jeu. 18 juil. 2019 21:03
par jchd
Oui, mais pas les caractères Unicode > 0xFF

Re: fciv et chcp ?

Posté : jeu. 18 juil. 2019 21:19
par papami
oui c'est vrai vous l'aviez dit au début et cela peut poser problème.
Il y a aussi -certutil mais je ne sais pas l'utiliser en direct comme dans la commande Run ... fciv en tête de ce fil
et si pas de probl. avec Unicode aussi...

Re: fciv et chcp ?

Posté : jeu. 18 juil. 2019 22:51
par Tlem
Pour fonctionner dans tous les cas avec fciv, alors la solution de renommage me semble la plus simple/fiable.

Sinon, la solution PowerShell devrait fonctionner pour tous les cas aussi.


Envoyé de mon Smartphone en utilisant Tapatalk