From af7f2ea958ba8ce52df131aae072af2fce611f0e Mon Sep 17 00:00:00 2001 From: MelvinFrederiks Date: Mon, 31 Aug 2026 14:10:42 +0200 Subject: [PATCH 1/6] Add a skip field in HashcatStatus If get_progress or get_progress_total is called with absolute=True, add the skip amount to the result. This restores behaviour desired in https://github.com/hashcat/hashcat/issues/4805 --- htpclient/hashcat_cracker.py | 5 ++++- htpclient/hashcat_status.py | 17 ++++++++++++----- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/htpclient/hashcat_cracker.py b/htpclient/hashcat_cracker.py index 06f900b..801b214 100644 --- a/htpclient/hashcat_cracker.py +++ b/htpclient/hashcat_cracker.py @@ -316,7 +316,10 @@ def run_loop(self, proc, chunk, task): else: identifier, line = item if identifier == 'OUT': - status = HashcatStatus(line.decode()) + if chunk['skip']: # is not None and is nonzero + status = HashcatStatus(line.decode(), chunk['skip']) + else: + status = HashcatStatus(line.decode()) if status.is_valid(): self.statusCount += 1 diff --git a/htpclient/hashcat_status.py b/htpclient/hashcat_status.py index a4369fe..e186c64 100644 --- a/htpclient/hashcat_status.py +++ b/htpclient/hashcat_status.py @@ -1,5 +1,5 @@ class HashcatStatus: - def __init__(self, line): + def __init__(self, line, skip=0): """ Initializes the HashcatStatus object by parsing a machine-readable status line from Hashcat. @@ -20,6 +20,7 @@ def __init__(self, line): self.temp = [] self.power = [] self.unknown_fields = False + self.skip = skip # https://github.com/hashcat/hashcat/issues/4805 try: fields = line.strip().split('\t') @@ -88,8 +89,11 @@ def __init__(self, line): def is_valid(self): return self.status >= 0 - def get_progress(self): - return self.progress[0] + def get_progress(self, absolute=False): + if absolute: + return self.progress[0] + self.skip + else: + return self.progress[0] def get_state(self): return self.status - 1 @@ -100,8 +104,11 @@ def get_curku(self): def get_temps(self): return self.temp - def get_progress_total(self): - return self.progress[1] + def get_progress_total(self, absolute=False): + if absolute: + return self.progress[1] + self.skip + else: + return self.progress[1] def get_all_util(self): return self.util From ed0efb618ac9d73fea3455708f349d4f811445a0 Mon Sep 17 00:00:00 2001 From: MelvinFrederiks Date: Mon, 31 Aug 2026 14:37:19 +0200 Subject: [PATCH 2/6] Remove absolute= kwarg, but only set skip if version if after 7.1.2 --- htpclient/hashcat_cracker.py | 6 ++++-- htpclient/hashcat_status.py | 14 ++++---------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/htpclient/hashcat_cracker.py b/htpclient/hashcat_cracker.py index 801b214..b3e36e8 100644 --- a/htpclient/hashcat_cracker.py +++ b/htpclient/hashcat_cracker.py @@ -316,8 +316,10 @@ def run_loop(self, proc, chunk, task): else: identifier, line = item if identifier == 'OUT': - if chunk['skip']: # is not None and is nonzero - status = HashcatStatus(line.decode(), chunk['skip']) + # sometime after the release of hashcat 7.1.2 the PROGRESS values both got decreased by the --skip amount + # This keeps track of this offset and adds it back, to preserve the old bevahiour + if chunk['skip'] and tuple(self.version_string.split('.')) > (7,1,2): + status = HashcatStatus(line.decode(), skip=chunk['skip']) else: status = HashcatStatus(line.decode()) if status.is_valid(): diff --git a/htpclient/hashcat_status.py b/htpclient/hashcat_status.py index e186c64..4f8ea8b 100644 --- a/htpclient/hashcat_status.py +++ b/htpclient/hashcat_status.py @@ -89,11 +89,8 @@ def __init__(self, line, skip=0): def is_valid(self): return self.status >= 0 - def get_progress(self, absolute=False): - if absolute: - return self.progress[0] + self.skip - else: - return self.progress[0] + def get_progress(self): + return self.progress[0] + self.skip def get_state(self): return self.status - 1 @@ -104,11 +101,8 @@ def get_curku(self): def get_temps(self): return self.temp - def get_progress_total(self, absolute=False): - if absolute: - return self.progress[1] + self.skip - else: - return self.progress[1] + def get_progress_total(self): + return self.progress[1] + self.skip def get_all_util(self): return self.util From 024be0e8a2d0c06a908ce9b36030647c441b4f3d Mon Sep 17 00:00:00 2001 From: MelvinFrederiks Date: Mon, 31 Aug 2026 14:57:50 +0200 Subject: [PATCH 3/6] Fix version tuple creation Also move version threshold to 7.2 --- htpclient/hashcat_cracker.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htpclient/hashcat_cracker.py b/htpclient/hashcat_cracker.py index b3e36e8..900c850 100644 --- a/htpclient/hashcat_cracker.py +++ b/htpclient/hashcat_cracker.py @@ -318,7 +318,8 @@ def run_loop(self, proc, chunk, task): if identifier == 'OUT': # sometime after the release of hashcat 7.1.2 the PROGRESS values both got decreased by the --skip amount # This keeps track of this offset and adds it back, to preserve the old bevahiour - if chunk['skip'] and tuple(self.version_string.split('.')) > (7,1,2): + version_tuple = tuple(int(s) for s in self.version_string.split('.')) + if chunk['skip'] and version_tuple >= (7,2): status = HashcatStatus(line.decode(), skip=chunk['skip']) else: status = HashcatStatus(line.decode()) From 30212adaa6e5baa6afd4184c5ab0f7385a1e7414 Mon Sep 17 00:00:00 2001 From: MelvinFrederiks Date: Mon, 31 Aug 2026 15:08:05 +0200 Subject: [PATCH 4/6] Remove github link --- htpclient/hashcat_status.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htpclient/hashcat_status.py b/htpclient/hashcat_status.py index 4f8ea8b..ba8ca75 100644 --- a/htpclient/hashcat_status.py +++ b/htpclient/hashcat_status.py @@ -20,7 +20,7 @@ def __init__(self, line, skip=0): self.temp = [] self.power = [] self.unknown_fields = False - self.skip = skip # https://github.com/hashcat/hashcat/issues/4805 + self.skip = skip try: fields = line.strip().split('\t') From 41b6a95a54c55823795a7a5f9f5e4bfe340fdcf4 Mon Sep 17 00:00:00 2001 From: MelvinFrederiks Date: Wed, 2 Sep 2026 11:11:19 +0200 Subject: [PATCH 5/6] Revert changes to getters: Instead adapt calculation of relative_progress. --- htpclient/hashcat_cracker.py | 14 +++++++------- htpclient/hashcat_status.py | 7 +++---- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/htpclient/hashcat_cracker.py b/htpclient/hashcat_cracker.py index 900c850..45fc4b9 100644 --- a/htpclient/hashcat_cracker.py +++ b/htpclient/hashcat_cracker.py @@ -316,13 +316,8 @@ def run_loop(self, proc, chunk, task): else: identifier, line = item if identifier == 'OUT': - # sometime after the release of hashcat 7.1.2 the PROGRESS values both got decreased by the --skip amount - # This keeps track of this offset and adds it back, to preserve the old bevahiour version_tuple = tuple(int(s) for s in self.version_string.split('.')) - if chunk['skip'] and version_tuple >= (7,2): - status = HashcatStatus(line.decode(), skip=chunk['skip']) - else: - status = HashcatStatus(line.decode()) + status = HashcatStatus(line.decode()) if status.is_valid(): self.statusCount += 1 @@ -350,7 +345,12 @@ def run_loop(self, proc, chunk, task): # we need to calculate the chunk start, because progress does not start at 0 for a chunk chunk_start = int(status.get_progress_total() / (chunk['skip'] + chunk['length']) * chunk['skip']) if total > 0: - relative_progress = int((status.get_progress() - chunk_start) / float(total - chunk_start) * 10000) + if version_tuple >= (7,2): + relative_progress = int(status.get_progress() / total * 10000) + else: + # Before hashcat 7.2, the PROGRESS fields included the skip value. + # Adjust for this offset + relative_progress = int((status.get_progress() - chunk_start) / float(total - chunk_start) * 10000) else: # this is the case when we cannot say anything about the progress relative_progress = 0 speed = status.get_speed() diff --git a/htpclient/hashcat_status.py b/htpclient/hashcat_status.py index ba8ca75..a4369fe 100644 --- a/htpclient/hashcat_status.py +++ b/htpclient/hashcat_status.py @@ -1,5 +1,5 @@ class HashcatStatus: - def __init__(self, line, skip=0): + def __init__(self, line): """ Initializes the HashcatStatus object by parsing a machine-readable status line from Hashcat. @@ -20,7 +20,6 @@ def __init__(self, line, skip=0): self.temp = [] self.power = [] self.unknown_fields = False - self.skip = skip try: fields = line.strip().split('\t') @@ -90,7 +89,7 @@ def is_valid(self): return self.status >= 0 def get_progress(self): - return self.progress[0] + self.skip + return self.progress[0] def get_state(self): return self.status - 1 @@ -102,7 +101,7 @@ def get_temps(self): return self.temp def get_progress_total(self): - return self.progress[1] + self.skip + return self.progress[1] def get_all_util(self): return self.util From 5477d83bfe2eaf1f525b269451a9798fb42f6508 Mon Sep 17 00:00:00 2001 From: MelvinFrederiks Date: Wed, 2 Sep 2026 15:08:00 +0200 Subject: [PATCH 6/6] Refine version cutoff for relative progress calculation determination --- htpclient/hashcat_cracker.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/htpclient/hashcat_cracker.py b/htpclient/hashcat_cracker.py index 45fc4b9..b01bb38 100644 --- a/htpclient/hashcat_cracker.py +++ b/htpclient/hashcat_cracker.py @@ -316,7 +316,10 @@ def run_loop(self, proc, chunk, task): else: identifier, line = item if identifier == 'OUT': - version_tuple = tuple(int(s) for s in self.version_string.split('.')) + # "7.1.2" -> (7,1,2) + # "7.1.2-546-gc885beef" -> (7,1,2,546) + version_list = self.version_string.replace('-', '.').split('.')[:4] # Chop off anything past the fourth field (for example commit hash) + version_tuple = tuple(int(s) for s in version_list) status = HashcatStatus(line.decode()) if status.is_valid(): self.statusCount += 1 @@ -345,10 +348,10 @@ def run_loop(self, proc, chunk, task): # we need to calculate the chunk start, because progress does not start at 0 for a chunk chunk_start = int(status.get_progress_total() / (chunk['skip'] + chunk['length']) * chunk['skip']) if total > 0: - if version_tuple >= (7,2): + if version_tuple >= (7, 1, 2, 546): relative_progress = int(status.get_progress() / total * 10000) else: - # Before hashcat 7.2, the PROGRESS fields included the skip value. + # before hashcat 7.1.2-546, the PROGRESS fields included the skip value. # Adjust for this offset relative_progress = int((status.get_progress() - chunk_start) / float(total - chunk_start) * 10000) else: # this is the case when we cannot say anything about the progress