Search this site
Embedded Files
Tyler Kruszewski ePortfolio
  • Home
  • Resume
  • High School
    • Hand Drafting & CADD
      • SolidWorks
      • AutoCAD
    • Projects
      • Class Projects
        • Rube Goldberg Challenge
        • Soldering
        • Coin Organizer
        • CNC - Wood
        • Plasma Cutter
        • Rocket Challenge
        • Multimeter
        • Automotive Aerodynamics
        • Robotics
          • Tello Drones
      • Personal Projects
        • Paddle Board+
        • DishBot
  • Personal
    • Google Apps Script
      • MAL to Google Sheet
      • Grade Database
    • Blender
    • MATLAB
      • MATLAB Fun
      • Prime Sieve
      • Factorial and Gamma
  • Virginia Tech
    • English 1106
    • Math 2114
    • CS 2104
    • Art 1604
  • Certificates & Awards
Tyler Kruszewski ePortfolio
  • Home
  • Resume
  • High School
    • Hand Drafting & CADD
      • SolidWorks
      • AutoCAD
    • Projects
      • Class Projects
        • Rube Goldberg Challenge
        • Soldering
        • Coin Organizer
        • CNC - Wood
        • Plasma Cutter
        • Rocket Challenge
        • Multimeter
        • Automotive Aerodynamics
        • Robotics
          • Tello Drones
      • Personal Projects
        • Paddle Board+
        • DishBot
  • Personal
    • Google Apps Script
      • MAL to Google Sheet
      • Grade Database
    • Blender
    • MATLAB
      • MATLAB Fun
      • Prime Sieve
      • Factorial and Gamma
  • Virginia Tech
    • English 1106
    • Math 2114
    • CS 2104
    • Art 1604
  • Certificates & Awards
  • More
    • Home
    • Resume
    • High School
      • Hand Drafting & CADD
        • SolidWorks
        • AutoCAD
      • Projects
        • Class Projects
          • Rube Goldberg Challenge
          • Soldering
          • Coin Organizer
          • CNC - Wood
          • Plasma Cutter
          • Rocket Challenge
          • Multimeter
          • Automotive Aerodynamics
          • Robotics
            • Tello Drones
        • Personal Projects
          • Paddle Board+
          • DishBot
    • Personal
      • Google Apps Script
        • MAL to Google Sheet
        • Grade Database
      • Blender
      • MATLAB
        • MATLAB Fun
        • Prime Sieve
        • Factorial and Gamma
    • Virginia Tech
      • English 1106
      • Math 2114
      • CS 2104
      • Art 1604
    • Certificates & Awards

CS 2104

Dictionary Attack Using Different Hash Algorithms
Dictionary's Used
Main
Iterative
Process Pool
i Process Pool
Several Processes
Several Threads
Several Processors Version 2
Several Processors Version 2 with Events
Several Processors Version 2 with Pipes
Several Processors with Pipes Version 2
Final Submission

As part of our final project we had 4 different options, 3 involving code, so here is my implementation.

Dictionary Attack Using Different Hash Algorithms

Overview: As part of this project, you will write a program that will measure password security by employing a variation of the dictionary attack. Given a file of a limited amount of words(100~200, no more than 500), allow the end user to pick up to any three words(due to limited computing power) from the word list to concatenate together in any order and form a random password. Write a program to crack that random password, and count how many attempts were made or/and how much time was consumed using a dictionary attack. Compare the efficiency of different hash algorithms. Plot a graph to visualize the difference.

Dictionary's Used

Simple Dictionary (34 Words)

the

of

to

and

a

in

is

it

you

that

he

was

for

on

are

with

as

I

his

they

be

at

one

have

this

from

or

had

by

not

word

but

what

some

Medium Dictionary (500 Words)

the

of

to

and

a

in

is

it

you

that

he

was

for

on

are

with

as

I

his

they

be

at

one

have

this

from

or

had

by

not

word

but

what

some

we

can

out

other

were

all

there

when

up

use

your

how

said

an

each

she

which

do

their

time

if

will

way

about

many

then

them

write

would

like

so

these

her

long

make

thing

see

him

two

has

look

more

day

could

go

come

did

number

sound

no

most

people

my

over

know

water

than

call

first

who

may

down

side

been

now

find

any

new

work

part

take

get

place

made

live

where

after

back

little

only

round

man

year

came

show

every

good

me

give

our

under

name

very

through

just

form

sentence

great

think

say

help

low

line

differ

turn

cause

much

mean

before

move

right

boy

old

too

same

tell

does

set

three

want

air

well

also

play

small

end

put

home

read

hand

port

large

spell

add

even

land

here

must

big

high

such

follow

act

why

ask

men

change

went

light

kind

off

need

house

picture

try

us

again

animal

point

mother

world

near

build

self

earth

father

head

stand

own

page

should

country

found

answer

school

grow

study

still

learn

plant

cover

food

sun

four

between

state

keep

eye

never

last

let

thought

city

tree

cross

farm

hard

start

might

story

saw

far

sea

draw

left

late

run

don't

while

press

close

night

real

life

few

north

open

seem

together

next

white

children

begin

got

walk

example

ease

paper

group

always

music

those

both

mark

often

letter

until

mile

river

car

feet

care

second

book

carry

took

science

eat

room

friend

began

idea

fish

mountain

stop

once

base

hear

horse

cut

sure

watch

color

face

wood

main

enough

plain

girl

usual

young

ready

above

ever

red

list

though

feel

talk

bird

soon

body

dog

family

direct

pose

leave

song

measure

door

product

black

short

numeral

class

wind

question

happen

complete

ship

area

half

rock

order

fire

south

problem

piece

told

knew

pass

since

top

whole

king

space

heard

best

hour

better

true

during

hundred

five

remember

step

early

hold

west

ground

interest

reach

fast

verb

sing

listen

six

table

travel

less

morning

ten

simple

several

vowel

toward

war

lay

against

pattern

slow

center

love

person

money

serve

appear

road

map

rain

rule

govern

pull

cold

notice

voice

unit

power

town

fine

certain

fly

fall

lead

cry

dark

machine

note

wait

plan

figure

star

box

noun

field

rest

correct

able

pound

done

beauty

drive

stood

contain

front

teach

week

final

gave

green

oh

quick

develop

ocean

warm

free

minute

strong

special

mind

behind

clear

tail

produce

fact

street

inch

multiply

nothing

course

stay

wheel

full

force

blue

object

decide

surface

deep

moon

island

foot

system

busy

test

record

boat

common

gold

possible

plane

stead

dry

wonder

laugh

thousand

ago

ran

check

game

shape

equate

hot

miss

brought

heat

snow

tire

bring

yes

distant

fill

east

paint

language

among

Large Dictionary (1000 Words)

the

of

to

and

a

in

is

it

you

that

he

was

for

on

are

with

as

I

his

they

be

at

one

have

this

from

or

had

by

not

word

but

what

some

we

can

out

other

were

all

there

when

up

use

your

how

said

an

each

she

which

do

their

time

if

will

way

about

many

then

them

write

would

like

so

these

her

long

make

thing

see

him

two

has

look

more

day

could

go

come

did

number

sound

no

most

people

my

over

know

water

than

call

first

who

may

down

side

been

now

find

any

new

work

part

take

get

place

made

live

where

after

back

little

only

round

man

year

came

show

every

good

me

give

our

under

name

very

through

just

form

sentence

great

think

say

help

low

line

differ

turn

cause

much

mean

before

move

right

boy

old

too

same

tell

does

set

three

want

air

well

also

play

small

end

put

home

read

hand

port

large

spell

add

even

land

here

must

big

high

such

follow

act

why

ask

men

change

went

light

kind

off

need

house

picture

try

us

again

animal

point

mother

world

near

build

self

earth

father

head

stand

own

page

should

country

found

answer

school

grow

study

still

learn

plant

cover

food

sun

four

between

state

keep

eye

never

last

let

thought

city

tree

cross

farm

hard

start

might

story

saw

far

sea

draw

left

late

run

don't

while

press

close

night

real

life

few

north

open

seem

together

next

white

children

begin

got

walk

example

ease

paper

group

always

music

those

both

mark

often

letter

until

mile

river

car

feet

care

second

book

carry

took

science

eat

room

friend

began

idea

fish

mountain

stop

once

base

hear

horse

cut

sure

watch

color

face

wood

main

enough

plain

girl

usual

young

ready

above

ever

red

list

though

feel

talk

bird

soon

body

dog

family

direct

pose

leave

song

measure

door

product

black

short

numeral

class

wind

question

happen

complete

ship

area

half

rock

order

fire

south

problem

piece

told

knew

pass

since

top

whole

king

space

heard

best

hour

better

true

during

hundred

five

remember

step

early

hold

west

ground

interest

reach

fast

verb

sing

listen

six

table

travel

less

morning

ten

simple

several

vowel

toward

war

lay

against

pattern

slow

center

love

person

money

serve

appear

road

map

rain

rule

govern

pull

cold

notice

voice

unit

power

town

fine

certain

fly

fall

lead

cry

dark

machine

note

wait

plan

figure

star

box

noun

field

rest

correct

able

pound

done

beauty

drive

stood

contain

front

teach

week

final

gave

green

oh

quick

develop

ocean

warm

free

minute

strong

special

mind

behind

clear

tail

produce

fact

street

inch

multiply

nothing

course

stay

wheel

full

force

blue

object

decide

surface

deep

moon

island

foot

system

busy

test

record

boat

common

gold

possible

plane

stead

dry

wonder

laugh

thousand

ago

ran

check

game

shape

equate

hot

miss

brought

heat

snow

tire

bring

yes

distant

fill

east

paint

language

among

grand

ball

yet

wave

drop

heart

am

present

heavy

dance

engine

position

arm

wide

sail

material

size

vary

settle

speak

weight

general

ice

matter

circle

pair

include

divide

syllable

felt

perhaps

pick

sudden

count

square

reason

length

represent

art

subject

region

energy

hunt

probable

bed

brother

egg

ride

cell

believe

fraction

forest

sit

race

window

store

summer

train

sleep

prove

lone

leg

exercise

wall

catch

mount

wish

sky

board

joy

winter

sat

written

wild

instrument

kept

glass

grass

cow

job

edge

sign

visit

past

soft

fun

bright

gas

weather

month

million

bear

finish

happy

hope

flower

clothe

strange

gone

jump

baby

eight

village

meet

root

buy

raise

solve

metal

whether

push

seven

paragraph

third

shall

held

hair

describe

cook

floor

either

result

burn

hill

safe

cat

century

consider

type

law

bit

coast

copy

phrase

silent

tall

sand

soil

roll

temperature

finger

industry

value

fight

lie

beat

excite

natural

view

sense

ear

else

quite

broke

case

middle

kill

son

lake

moment

scale

loud

spring

observe

child

straight

consonant

nation

dictionary

milk

speed

method

organ

pay

age

section

dress

cloud

surprise

quiet

stone

tiny

climb

cool

design

poor

lot

experiment

bottom

key

iron

single

stick

flat

twenty

skin

smile

crease

hole

trade

melody

trip

office

receive

row

mouth

exact

symbol

die

least

trouble

shout

except

wrote

seed

tone

join

suggest

clean

break

lady

yard

rise

bad

blow

oil

blood

touch

grew

cent

mix

team

wire

cost

lost

brown

wear

garden

equal

sent

choose

fell

fit

flow

fair

bank

collect

save

control

decimal

gentle

woman

captain

practice

separate

difficult

doctor

please

protect

noon

whose

locate

ring

character

insect

caught

period

indicate

radio

spoke

atom

human

history

effect

electric

expect

crop

modern

element

hit

student

corner

party

supply

bone

rail

imagine

provide

agree

thus

capital

won't

chair

danger

fruit

rich

thick

soldier

process

operate

guess

necessary

sharp

wing

create

neighbor

wash

bat

rather

crowd

corn

compare

poem

string

bell

depend

meat

rub

tube

famous

dollar

stream

fear

sight

thin

triangle

planet

hurry

chief

colony

clock

mine

tie

enter

major

fresh

search

send

yellow

gun

allow

print

dead

spot

desert

suit

current

lift

rose

continue

block

chart

hat

sell

success

company

subtract

event

particular

deal

swim

term

opposite

wife

shoe

shoulder

spread

arrange

camp

invent

cotton

born

determine

quart

nine

truck

noise

level

chance

gather

shop

stretch

throw

shine

property

column

molecule

select

wrong

gray

repeat

require

broad

prepare

salt

nose

plural

anger

claim

continent

oxygen

sugar

death

pretty

skill

women

season

solution

magnet

silver

thank

branch

match

suffix

especially

fig

afraid

huge

sister

steel

discuss

forward

similar

guide

experience

score

apple

bought

led

pitch

coat

mass

card

band

rope

slip

win

dream

evening

condition

feed

tool

total

basic

smell

valley

nor

double

seat

arrive

master

track

parent

shore

division

sheet

substance

favor

connect

post

spend

chord

fat

glad

original

share

station

dad

bread

charge

proper

bar

offer

segment

slave

duck

instant

market

degree

populate

chick

dear

enemy

reply

drink

occur

support

speech

nature

range

steam

motion

path

liquid

log

meant

quotient

teeth

shell

neck

Main

The main method is the thing that will actually call the different Hash Test functions as well as get user input and latter on make the graphs. The main function is largely the same across all functions except for the call to the function replacing the HashFunction that is currently in the code.

Main Code

import itertools

import hashlib

import multiprocessing.shared_memory

import matplotlib as plt

import time

import multiprocessing 

import threading

import functools 

import cProfile

import math

import ctypes


#Converges the geometric series for when starting at 1

def geometricSeries(a: int, r: int, n: int):

    return a * r * ((r ** n - 1) // (r - 1)) 


if __name__ == "__main__":

    wordLimit = 3

    dictonaryName = "MediumDictionary.txt"

    hashAlgorithms = ['sha256', 'sha512']

    f = open(dictonaryName, "r")

    words = f.read().splitlines()

    f.close()

    maxCount = geometricSeries(1,len(words),wordLimit)

    print(f"Longest Password is {words[-1] * wordLimit} and will take around {maxCount} iterations and around {maxCount * 6e-7} seconds")


    password = input("Enter Password: ")

    while password != "q":

        for h in hashAlgorithms:

            hash = hashlib.new(h)

            hash.update(password.encode()) #Hashes the password

            print(f"{h.capitalize()} Hash: {hash.hexdigest()}") #Prints nice Hex

            breakCount, breakTime, value = HashFunction(wordLimit, words, hash.digest(), h)

            cProfile.run('HashFunction(wordLimit, words, hash.digest(), h)')

            print(breakCount, breakTime, value)

        password = input("Enter Password: ")

    print("Done") 

Iterative

The first approach was of course to do a simple for loop which ended up taking around ~3 minutes to do the hardest password in the 500 word dictionary of amongamongamong. In the profiler we see that it takes this long due solely to having lots of iterations with a total of 125,250,500 iterations of the loop.

Iterative Code

def hashAttack(wordLimit: int, words: list, password: bytes, algorithm: str):

    start = time.time_ns()

    count = 0

    for i in range(1, wordLimit + 1):

        perms = itertools.product(words, repeat=i)

        for p in perms:

            test = "".join([s for s in p]).encode()

            hash = hashlib.new(algorithm)

            hash.update(test)

            count += 1

            if (hash.digest() == password):

                return count, (time.time_ns() - start) / 1e9, test

    return None, None 

cProfile

Longest Password is amongamongamong and will take around 125250500 iterations and around 75.1503 seconds

Enter Password: amongamongamong

Sha256 Hash: 922f052e4cc8f014de935fb51ed139c1e21d091accf6c9d1f89f2c41310e0969

         876753507 function calls in 363.562 seconds


   Ordered by: standard name


   ncalls  tottime  percall  cumtime  percall filename:lineno(function)

        1    0.000    0.000  363.562  363.562 <string>:1(<module>)

        1  177.490  177.490  363.562  363.562 DicAttack.py:17(hashAttack)

125250500   22.976    0.000   22.976    0.000 DicAttack.py:23(<listcomp>)

125250500   35.692    0.000   74.187    0.000 hashlib.py:152(__hash_new)

125250500   38.495    0.000   38.495    0.000 {built-in method _hashlib.new}

        1    0.000    0.000  363.562  363.562 {built-in method builtins.exec}

        2    0.000    0.000    0.000    0.000 {built-in method time.time_ns}

125250501   48.585    0.000   48.585    0.000 {method 'digest' of '_hashlib.HASH' objects}

        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

125250500   12.388    0.000   12.388    0.000 {method 'encode' of 'str' objects}

125250500   15.395    0.000   15.395    0.000 {method 'join' of 'str' objects}

125250500   12.541    0.000   12.541    0.000 {method 'update' of '_hashlib.HASH' objects}



125250500 168.0729339 b'amongamongamong'

Sha512 Hash: 0c0861dc3779cc1e7cc7b1edcdd1864617f3f4c67656724e47c94033ced9f1c0750807a20a7283df8cc52c27d3814fd5200d9ab27d308aaa7df550a70f155249

         876753507 function calls in 385.726 seconds


   Ordered by: standard name


   ncalls  tottime  percall  cumtime  percall filename:lineno(function)

        1    0.000    0.000  385.726  385.726 <string>:1(<module>)

        1  177.534  177.534  385.726  385.726 DicAttack.py:17(hashAttack)

125250500   20.505    0.000   20.505    0.000 DicAttack.py:23(<listcomp>)

125250500   35.177    0.000   73.378    0.000 hashlib.py:152(__hash_new)

125250500   38.201    0.000   38.201    0.000 {built-in method _hashlib.new}

        1    0.000    0.000  385.726  385.726 {built-in method builtins.exec}

        2    0.000    0.000    0.000    0.000 {built-in method time.time_ns}

125250501   73.758    0.000   73.758    0.000 {method 'digest' of '_hashlib.HASH' objects}

        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

125250500   12.188    0.000   12.188    0.000 {method 'encode' of 'str' objects}

125250500   15.634    0.000   15.634    0.000 {method 'join' of 'str' objects}

125250500   12.729    0.000   12.729    0.000 {method 'update' of '_hashlib.HASH' objects}



125250500 189.4634892 b'amongamongamong'

Enter Password: q

Done

Process Pool

Since the for loop took so long due to the number of iterations then the easiest way to fix that is to parallelize it leading to using a multiprocessor pool. This approach took around ~75 seconds to do the hardest password in the 500 word dictionary of amongamongamong. In the profiler we see that the bottle neck is using locks, which I suspect is due to the multiprocessor since my code doesn't use locks. However there is a even bigger issue which is no early termination meaning it will test every possible permutation instead of only testing a few.

Process Pool Code

def run(password, algorithm, p):

    test = "".join([s for s in p]).encode()

    hash = hashlib.new(algorithm)

    hash.update(test)

    if (hash.digest() == password):

        return True

    return None


def multiHashAttack(wordLimit: int, words: list, password: bytes, algorithm: str):

    start = time.time_ns()

    count = 1

    func = functools.partial(run, password, algorithm)

    pool = multiprocessing.Pool()

    for i in range(1, wordLimit + 1):

        perms = itertools.product(words, repeat=i)

        values = pool.map(func, perms)

        try:

            count += values.index(True)

            pool.close()

            pool.join()

            return count, (time.time_ns() - start) / 1e9, None

        except:

            count += len(values)

    pool.close()

    pool.join()

    return None, None 

cProfile

Longest Password is amongamongamong and will take around 125250500 iterations and around 75.1503 seconds

Enter Password: amongamongamong

Sha256 Hash: 922f052e4cc8f014de935fb51ed139c1e21d091accf6c9d1f89f2c41310e0969

         4628 function calls in 87.265 seconds


   Ordered by: standard name


   ncalls  tottime  percall  cumtime  percall filename:lineno(function)

       55    0.000    0.000    0.000    0.000 <frozen importlib._bootstrap>:405(parent)

        3    0.000    0.000    0.000    0.000 <frozen ntpath>:107(join)

        6    0.000    0.000    0.000    0.000 <frozen ntpath>:154(splitdrive)

       16    0.000    0.000    0.000    0.000 <frozen ntpath>:538(normpath)

       16    0.000    0.000    0.000    0.000 <frozen ntpath>:87(isabs)

        1    0.159    0.159   87.265   87.265 <string>:1(<module>)

        1    0.002    0.002   87.104   87.104 DicAttack.py:39(multiHashAttack)

       19    0.000    0.000    0.000    0.000 _weakrefset.py:39(_remove)

       19    0.000    0.000    0.000    0.000 _weakrefset.py:85(add)

        6    0.000    0.000    0.000    0.000 connection.py:118(__init__)

        6    0.000    0.000    0.000    0.000 connection.py:131(__del__)

       68    0.000    0.000    0.000    0.000 connection.py:135(_check_closed)

        4    0.000    0.000    0.000    0.000 connection.py:143(_check_writable)

      128    0.000    0.000    0.000    0.000 connection.py:159(readable)

      128    0.000    0.000    0.000    0.000 connection.py:164(writable)

       64    0.000    0.000    0.000    0.000 connection.py:169(fileno)

        4    0.000    0.000    0.000    0.000 connection.py:182(send_bytes)

        6    0.000    0.000    0.000    0.000 connection.py:277(_close)

        4    0.000    0.000    0.000    0.000 connection.py:284(_send_bytes)

        3    0.000    0.000    0.002    0.001 connection.py:552(Pipe)

        3    0.001    0.000    0.002    0.001 connection.py:70(arbitrary_address)

       64    0.000    0.000    0.001    0.000 connection.py:973(reduce_pipe_connection)

        3    0.000    0.000    0.003    0.001 context.py:110(SimpleQueue)

        1    0.000    0.000    0.097    0.097 context.py:115(Pool)

        6    0.000    0.000    0.000    0.000 context.py:187(get_context)

        3    0.000    0.000    0.000    0.000 context.py:197(get_start_method)

        1    0.000    0.000    0.000    0.000 context.py:237(get_context)

       16    0.000    0.000    0.000    0.000 context.py:253(get_start_method)

       16    0.000    0.000    0.087    0.005 context.py:333(_Popen)

      160    0.000    0.000    0.000    0.000 context.py:365(get_spawning_popen)

       32    0.000    0.000    0.000    0.000 context.py:368(set_spawning_popen)

       64    0.000    0.000    0.000    0.000 context.py:371(assert_spawning)

        3    0.000    0.000    0.000    0.000 context.py:65(Lock)

        1    0.000    0.000    0.000    0.000 pool.py:157(__init__)

       16    0.000    0.000    0.001    0.000 pool.py:179(Process)

        1    0.000    0.000    0.097    0.097 pool.py:183(__init__)

        1    0.000    0.000    0.000    0.000 pool.py:266(__del__)

        1    0.000    0.000    0.000    0.000 pool.py:279(_get_sentinels)

        1    0.000    0.000    0.089    0.089 pool.py:305(_repopulate_pool)

        1    0.000    0.000    0.089    0.089 pool.py:314(_repopulate_pool_static)

        1    0.000    0.000    0.003    0.003 pool.py:345(_setup_queues)

        3    0.000    0.000    0.000    0.000 pool.py:351(_check_running)

        3    0.000    0.000   85.196   28.399 pool.py:362(map)

        3    7.982    2.661    8.133    2.711 pool.py:471(_map_async)

        1    0.000    0.000    0.000    0.000 pool.py:647(close)

        1    0.000    0.000    0.336    0.336 pool.py:659(join)

        1    0.000    0.000    0.000    0.000 pool.py:671(_help_stuff_finish)

        1    0.000    0.000    0.000    0.000 pool.py:680(_terminate_pool)

        3    0.000    0.000    0.000    0.000 pool.py:747(__init__)

        3    0.000    0.000    0.000    0.000 pool.py:756(ready)

        3    0.000    0.000   77.063   25.688 pool.py:764(wait)

        3    0.000    0.000   77.063   25.688 pool.py:767(get)

        3    0.151    0.050    0.151    0.050 pool.py:796(__init__)

      168    0.000    0.000    0.335    0.002 popen_spawn_win32.py:103(wait)

      152    0.000    0.000    0.001    0.000 popen_spawn_win32.py:121(poll)

       16    0.000    0.000    0.001    0.000 popen_spawn_win32.py:29(_close_handles)

       16    0.001    0.000    0.087    0.005 popen_spawn_win32.py:45(__init__)

       80    0.000    0.000    0.000    0.000 popen_spawn_win32.py:70(<genexpr>)

       32    0.000    0.000    0.000    0.000 popen_spawn_win32.py:99(duplicate_for_child)

       16    0.000    0.000    0.088    0.006 process.py:110(start)

       16    0.000    0.000    0.335    0.021 process.py:142(join)

       16    0.000    0.000    0.000    0.000 process.py:153(is_alive)

       32    0.000    0.000    0.000    0.000 process.py:189(name)

       16    0.000    0.000    0.000    0.000 process.py:193(name)

       16    0.000    0.000    0.000    0.000 process.py:205(daemon)

       16    0.000    0.000    0.000    0.000 process.py:213(authkey)

       16    0.000    0.000    0.000    0.000 process.py:224(exitcode)

       32    0.000    0.000    0.001    0.000 process.py:350(__reduce__)

       35    0.000    0.000    0.000    0.000 process.py:37(current_process)

       16    0.000    0.000    0.001    0.000 process.py:61(_cleanup)

       16    0.000    0.000    0.001    0.000 process.py:80(__init__)

       32    0.000    0.000    0.000    0.000 process.py:94(<genexpr>)

       64    0.000    0.000    0.000    0.000 process.py:99(_check_closed)

        3    0.000    0.000    0.003    0.001 queues.py:339(__init__)

       32    0.000    0.000    0.000    0.000 queues.py:355(__getstate__)

        4    0.000    0.000    0.000    0.000 queues.py:369(put)

        6    0.000    0.000    0.000    0.000 random.py:480(choices)

        6    0.000    0.000    0.000    0.000 random.py:493(<listcomp>)

       64    0.000    0.000    0.001    0.000 reduction.py:106(__init__)

       36    0.000    0.000    0.001    0.000 reduction.py:38(__init__)

        4    0.000    0.000    0.000    0.000 reduction.py:48(dumps)

       32    0.000    0.000    0.005    0.000 reduction.py:58(dump)

       32    0.000    0.000    0.000    0.000 reduction.py:71(duplicate)

       16    0.000    0.000    0.000    0.000 spawn.py:138(_check_not_importing_main)

       16    0.001    0.000    0.001    0.000 spawn.py:160(get_preparation_data)

       32    0.000    0.000    0.000    0.000 spawn.py:45(get_executable)

       16    0.000    0.000    0.001    0.000 spawn.py:83(get_command_line)

       48    0.000    0.000    0.000    0.000 spawn.py:92(<genexpr>)

       16    0.000    0.000    0.000    0.000 subprocess.py:290(_optim_args_from_interpreter_flags)

       16    0.000    0.000    0.000    0.000 subprocess.py:300(_args_from_interpreter_flags)

       32    0.000    0.000    0.000    0.000 synchronize.py:100(__getstate__)

        3    0.000    0.000    0.000    0.000 synchronize.py:121(_make_name)

        3    0.000    0.000    0.000    0.000 synchronize.py:168(__init__)

        3    0.000    0.000    0.000    0.000 synchronize.py:50(__init__)

        3    0.000    0.000    0.000    0.000 synchronize.py:90(_make_methods)

        6    0.000    0.000    0.000    0.000 tempfile.py:143(rng)

        6    0.000    0.000    0.001    0.000 tempfile.py:154(__next__)

        3    0.000    0.000    0.000    0.000 tempfile.py:230(_get_candidate_names)

        3    0.000    0.000    0.001    0.000 tempfile.py:401(mktemp)

        3    0.000    0.000    0.000    0.000 tempfile.py:77(_exists)

        3    0.000    0.000    0.000    0.000 threading.py:1051(_stop)

        6    0.000    0.000    0.001    0.000 threading.py:1087(join)

        6    0.000    0.000    0.001    0.000 threading.py:1125(_wait_for_tstate_lock)

        2    0.000    0.000    0.000    0.000 threading.py:1192(is_alive)

        6    0.000    0.000    0.000    0.000 threading.py:1206(daemon)

        3    0.000    0.000    0.000    0.000 threading.py:1221(daemon)

        3    0.000    0.000    0.000    0.000 threading.py:1324(_make_invoke_excepthook)

       12    0.000    0.000    0.000    0.000 threading.py:1453(current_thread)

        6    0.000    0.000    0.000    0.000 threading.py:243(__init__)

        6    0.000    0.000    0.000    0.000 threading.py:271(__enter__)

        6    0.000    0.000    0.000    0.000 threading.py:274(__exit__)

        6    0.000    0.000    0.000    0.000 threading.py:280(_release_save)

        6    0.000    0.000    0.000    0.000 threading.py:283(_acquire_restore)

        6    0.000    0.000    0.000    0.000 threading.py:286(_is_owned)

        6    0.000    0.000   77.067   12.844 threading.py:295(wait)

        6    0.000    0.000    0.000    0.000 threading.py:562(__init__)

       15    0.000    0.000    0.000    0.000 threading.py:575(is_set)

        6    0.000    0.000   77.067   12.844 threading.py:611(wait)

        3    0.000    0.000    0.000    0.000 threading.py:811(_newname)

        3    0.000    0.000    0.000    0.000 threading.py:856(__init__)

        3    0.000    0.000    0.004    0.001 threading.py:945(start)

       17    0.000    0.000    0.000    0.000 util.py:189(__init__)

       17    0.000    0.000    0.001    0.000 util.py:208(__call__)

       17    0.000    0.000    0.000    0.000 util.py:44(sub_debug)

       29    0.000    0.000    0.000    0.000 util.py:48(debug)

       12    0.000    0.000    0.000    0.000 {built-in method _thread.allocate_lock}

       12    0.000    0.000    0.000    0.000 {built-in method _thread.get_ident}

        3    0.000    0.000    0.000    0.000 {built-in method _thread.start_new_thread}

      118    0.001    0.000    0.001    0.000 {built-in method _winapi.CloseHandle}

        3    0.000    0.000    0.000    0.000 {built-in method _winapi.ConnectNamedPipe}

        3    0.000    0.000    0.000    0.000 {built-in method _winapi.CreateFile}

        3    0.000    0.000    0.000    0.000 {built-in method _winapi.CreateNamedPipe}

       16    0.000    0.000    0.000    0.000 {built-in method _winapi.CreatePipe}

       16    0.078    0.005    0.078    0.005 {built-in method _winapi.CreateProcess}

       96    0.000    0.000    0.000    0.000 {built-in method _winapi.DuplicateHandle}

       96    0.000    0.000    0.000    0.000 {built-in method _winapi.GetCurrentProcess}

       16    0.000    0.000    0.000    0.000 {built-in method _winapi.GetExitCodeProcess}

       64    0.000    0.000    0.000    0.000 {built-in method _winapi.OpenProcess}

        3    0.000    0.000    0.000    0.000 {built-in method _winapi.SetNamedPipeHandleState}

      136    0.335    0.002    0.335    0.002 {built-in method _winapi.WaitForSingleObject}

        4    0.000    0.000    0.000    0.000 {built-in method _winapi.WriteFile}

        3    0.000    0.000    0.000    0.000 {built-in method builtins.divmod}

        1    0.001    0.001   87.265   87.265 {built-in method builtins.exec}

      342    0.000    0.000    0.000    0.000 {built-in method builtins.getattr}

        5    0.000    0.000    0.000    0.000 {built-in method builtins.hasattr}

       55    0.000    0.000    0.000    0.000 {built-in method builtins.isinstance}

       33    0.000    0.000    0.000    0.000 {built-in method builtins.len}

      120    0.000    0.000    0.000    0.000 {built-in method builtins.max}

       45    0.000    0.000    0.001    0.000 {built-in method builtins.next}

       16    0.000    0.000    0.000    0.000 {built-in method io.open}

       48    0.000    0.000    0.000    0.000 {built-in method math.floor}

       16    0.000    0.000    0.000    0.000 {built-in method msvcrt.open_osfhandle}

       16    0.000    0.000    0.000    0.000 {built-in method nt._path_normpath}

        1    0.000    0.000    0.000    0.000 {built-in method nt.cpu_count}

       41    0.000    0.000    0.000    0.000 {built-in method nt.fspath}

       16    0.000    0.000    0.000    0.000 {built-in method nt.getcwd}

      187    0.000    0.000    0.000    0.000 {built-in method nt.getpid}

        3    0.000    0.000    0.000    0.000 {built-in method nt.lstat}

        2    0.000    0.000    0.000    0.000 {built-in method time.time_ns}

        7    0.000    0.000    0.000    0.000 {method 'GetOverlappedResult' of '_winapi.Overlapped' objects}

        6    0.000    0.000    0.000    0.000 {method '__enter__' of '_thread.lock' objects}

       16    0.000    0.000    0.000    0.000 {method '__exit__' of '_io._IOBase' objects}

        3    0.000    0.000    0.000    0.000 {method '__exit__' of '_thread.RLock' objects}

        6    0.000    0.000    0.000    0.000 {method '__exit__' of '_thread.lock' objects}

        1    0.000    0.000    0.000    0.000 {method 'acquire' of '_multiprocessing.SemLock' objects}

       27   77.067    2.854   77.067    2.854 {method 'acquire' of '_thread.lock' objects}

       35    0.000    0.000    0.000    0.000 {method 'add' of 'set' objects}

        6    0.000    0.000    0.000    0.000 {method 'append' of 'collections.deque' objects}

       16    0.000    0.000    0.000    0.000 {method 'append' of 'list' objects}

       52    0.000    0.000    0.000    0.000 {method 'copy' of 'dict' objects}

       16    0.000    0.000    0.000    0.000 {method 'copy' of 'list' objects}

        1    0.000    0.000    0.000    0.000 {method 'digest' of '_hashlib.HASH' objects}

        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

       51    0.000    0.000    0.000    0.000 {method 'discard' of 'set' objects}

       36    0.002    0.000    0.004    0.000 {method 'dump' of '_pickle.Pickler' objects}

        6    0.000    0.000    0.000    0.000 {method 'find' of 'str' objects}

       16    0.000    0.000    0.000    0.000 {method 'get' of 'dict' objects}

        4    0.000    0.000    0.000    0.000 {method 'getbuffer' of '_io.BytesIO' objects}

       19    1.472    0.077    1.472    0.077 {method 'index' of 'list' objects}

       32    0.000    0.000    0.000    0.000 {method 'items' of 'dict' objects}

       54    0.000    0.000    0.000    0.000 {method 'join' of 'str' objects}

        3    0.000    0.000    0.000    0.000 {method 'locked' of '_thread.lock' objects}

        3    0.000    0.000    0.000    0.000 {method 'put' of '_queue.SimpleQueue' objects}

       48    0.000    0.000    0.000    0.000 {method 'random' of '_random.Random' objects}

        9    0.000    0.000    0.000    0.000 {method 'release' of '_thread.lock' objects}

       35    0.000    0.000    0.000    0.000 {method 'replace' of 'str' objects}

       55    0.000    0.000    0.000    0.000 {method 'rpartition' of 'str' objects}

       32    0.000    0.000    0.000    0.000 {method 'startswith' of 'str' objects}

       52    0.000    0.000    0.000    0.000 {method 'update' of 'dict' objects}

        3    0.000    0.000    0.000    0.000 {method 'upper' of 'str' objects}



125250500 72.8165352 None

Sha512 Hash: 0c0861dc3779cc1e7cc7b1edcdd1864617f3f4c67656724e47c94033ced9f1c0750807a20a7283df8cc52c27d3814fd5200d9ab27d308aaa7df550a70f155249

         4628 function calls in 82.392 seconds


   Ordered by: standard name


   ncalls  tottime  percall  cumtime  percall filename:lineno(function)

       55    0.000    0.000    0.000    0.000 <frozen importlib._bootstrap>:405(parent)

        3    0.000    0.000    0.000    0.000 <frozen ntpath>:107(join)

        6    0.000    0.000    0.000    0.000 <frozen ntpath>:154(splitdrive)

       16    0.000    0.000    0.000    0.000 <frozen ntpath>:538(normpath)

       16    0.000    0.000    0.000    0.000 <frozen ntpath>:87(isabs)

        1    0.146    0.146   82.392   82.392 <string>:1(<module>)

        1    0.001    0.001   82.245   82.245 DicAttack.py:39(multiHashAttack)

       19    0.000    0.000    0.000    0.000 _weakrefset.py:39(_remove)

       19    0.000    0.000    0.000    0.000 _weakrefset.py:85(add)

        6    0.000    0.000    0.000    0.000 connection.py:118(__init__)

        6    0.000    0.000    0.000    0.000 connection.py:131(__del__)

       68    0.000    0.000    0.000    0.000 connection.py:135(_check_closed)

        4    0.000    0.000    0.000    0.000 connection.py:143(_check_writable)

      128    0.000    0.000    0.000    0.000 connection.py:159(readable)

      128    0.000    0.000    0.000    0.000 connection.py:164(writable)

       64    0.000    0.000    0.000    0.000 connection.py:169(fileno)

        4    0.000    0.000    0.000    0.000 connection.py:182(send_bytes)

        6    0.000    0.000    0.000    0.000 connection.py:277(_close)

        4    0.000    0.000    0.000    0.000 connection.py:284(_send_bytes)

        3    0.000    0.000    0.001    0.000 connection.py:552(Pipe)

        3    0.000    0.000    0.000    0.000 connection.py:70(arbitrary_address)

       64    0.000    0.000    0.001    0.000 connection.py:973(reduce_pipe_connection)

        3    0.000    0.000    0.001    0.000 context.py:110(SimpleQueue)

        1    0.000    0.000    0.083    0.083 context.py:115(Pool)

        6    0.000    0.000    0.000    0.000 context.py:187(get_context)

        3    0.000    0.000    0.000    0.000 context.py:197(get_start_method)

        1    0.000    0.000    0.000    0.000 context.py:237(get_context)

       16    0.000    0.000    0.000    0.000 context.py:253(get_start_method)

       16    0.000    0.000    0.077    0.005 context.py:333(_Popen)

      160    0.000    0.000    0.000    0.000 context.py:365(get_spawning_popen)

       32    0.000    0.000    0.000    0.000 context.py:368(set_spawning_popen)

       64    0.000    0.000    0.000    0.000 context.py:371(assert_spawning)

        3    0.000    0.000    0.000    0.000 context.py:65(Lock)

        1    0.000    0.000    0.000    0.000 pool.py:157(__init__)

       16    0.000    0.000    0.001    0.000 pool.py:179(Process)

        1    0.000    0.000    0.082    0.082 pool.py:183(__init__)

        1    0.000    0.000    0.000    0.000 pool.py:266(__del__)

        1    0.000    0.000    0.000    0.000 pool.py:279(_get_sentinels)

        1    0.000    0.000    0.079    0.079 pool.py:305(_repopulate_pool)

        1    0.000    0.000    0.079    0.079 pool.py:314(_repopulate_pool_static)

        1    0.000    0.000    0.001    0.001 pool.py:345(_setup_queues)

        3    0.000    0.000    0.000    0.000 pool.py:351(_check_running)

        3    0.000    0.000   80.362   26.787 pool.py:362(map)

        3    8.624    2.875    8.758    2.919 pool.py:471(_map_async)

        1    0.000    0.000    0.000    0.000 pool.py:647(close)

        1    0.000    0.000    0.277    0.277 pool.py:659(join)

        1    0.000    0.000    0.000    0.000 pool.py:671(_help_stuff_finish)

        1    0.000    0.000    0.000    0.000 pool.py:680(_terminate_pool)

        3    0.000    0.000    0.000    0.000 pool.py:747(__init__)

        3    0.000    0.000    0.000    0.000 pool.py:756(ready)

        3    0.000    0.000   71.604   23.868 pool.py:764(wait)

        3    0.000    0.000   71.604   23.868 pool.py:767(get)

        3    0.134    0.045    0.134    0.045 pool.py:796(__init__)

      168    0.000    0.000    0.276    0.002 popen_spawn_win32.py:103(wait)

      152    0.000    0.000    0.000    0.000 popen_spawn_win32.py:121(poll)

       16    0.000    0.000    0.001    0.000 popen_spawn_win32.py:29(_close_handles)

       16    0.001    0.000    0.077    0.005 popen_spawn_win32.py:45(__init__)

       80    0.000    0.000    0.000    0.000 popen_spawn_win32.py:70(<genexpr>)

       32    0.000    0.000    0.000    0.000 popen_spawn_win32.py:99(duplicate_for_child)

       16    0.000    0.000    0.078    0.005 process.py:110(start)

       16    0.000    0.000    0.276    0.017 process.py:142(join)

       16    0.000    0.000    0.000    0.000 process.py:153(is_alive)

       32    0.000    0.000    0.000    0.000 process.py:189(name)

       16    0.000    0.000    0.000    0.000 process.py:193(name)

       16    0.000    0.000    0.000    0.000 process.py:205(daemon)

       16    0.000    0.000    0.000    0.000 process.py:213(authkey)

       16    0.000    0.000    0.000    0.000 process.py:224(exitcode)

       32    0.000    0.000    0.000    0.000 process.py:350(__reduce__)

       35    0.000    0.000    0.000    0.000 process.py:37(current_process)

       16    0.000    0.000    0.001    0.000 process.py:61(_cleanup)

       16    0.000    0.000    0.001    0.000 process.py:80(__init__)

       32    0.000    0.000    0.000    0.000 process.py:94(<genexpr>)

       64    0.000    0.000    0.000    0.000 process.py:99(_check_closed)

        3    0.000    0.000    0.001    0.000 queues.py:339(__init__)

       32    0.000    0.000    0.000    0.000 queues.py:355(__getstate__)

        4    0.000    0.000    0.001    0.000 queues.py:369(put)

        6    0.000    0.000    0.000    0.000 random.py:480(choices)

        6    0.000    0.000    0.000    0.000 random.py:493(<listcomp>)

       64    0.000    0.000    0.001    0.000 reduction.py:106(__init__)

       36    0.000    0.000    0.001    0.000 reduction.py:38(__init__)

        4    0.000    0.000    0.000    0.000 reduction.py:48(dumps)

       32    0.001    0.000    0.005    0.000 reduction.py:58(dump)

       32    0.000    0.000    0.000    0.000 reduction.py:71(duplicate)

       16    0.000    0.000    0.000    0.000 spawn.py:138(_check_not_importing_main)

       16    0.000    0.000    0.001    0.000 spawn.py:160(get_preparation_data)

       32    0.000    0.000    0.000    0.000 spawn.py:45(get_executable)

       16    0.000    0.000    0.001    0.000 spawn.py:83(get_command_line)

       48    0.000    0.000    0.000    0.000 spawn.py:92(<genexpr>)

       16    0.000    0.000    0.000    0.000 subprocess.py:290(_optim_args_from_interpreter_flags)

       16    0.000    0.000    0.000    0.000 subprocess.py:300(_args_from_interpreter_flags)

       32    0.000    0.000    0.000    0.000 synchronize.py:100(__getstate__)

        3    0.000    0.000    0.000    0.000 synchronize.py:121(_make_name)

        3    0.000    0.000    0.000    0.000 synchronize.py:168(__init__)

        3    0.000    0.000    0.000    0.000 synchronize.py:50(__init__)

        3    0.000    0.000    0.000    0.000 synchronize.py:90(_make_methods)

        6    0.000    0.000    0.000    0.000 tempfile.py:143(rng)

        6    0.000    0.000    0.000    0.000 tempfile.py:154(__next__)

        3    0.000    0.000    0.000    0.000 tempfile.py:230(_get_candidate_names)

        3    0.000    0.000    0.000    0.000 tempfile.py:401(mktemp)

        3    0.000    0.000    0.000    0.000 tempfile.py:77(_exists)

        3    0.000    0.000    0.000    0.000 threading.py:1051(_stop)

        6    0.000    0.000    0.001    0.000 threading.py:1087(join)

        6    0.000    0.000    0.001    0.000 threading.py:1125(_wait_for_tstate_lock)

        2    0.000    0.000    0.000    0.000 threading.py:1192(is_alive)

        6    0.000    0.000    0.000    0.000 threading.py:1206(daemon)

        3    0.000    0.000    0.000    0.000 threading.py:1221(daemon)

        3    0.000    0.000    0.000    0.000 threading.py:1324(_make_invoke_excepthook)

       12    0.000    0.000    0.000    0.000 threading.py:1453(current_thread)

        6    0.000    0.000    0.000    0.000 threading.py:243(__init__)

        6    0.000    0.000    0.000    0.000 threading.py:271(__enter__)

        6    0.000    0.000    0.000    0.000 threading.py:274(__exit__)

        6    0.000    0.000    0.000    0.000 threading.py:280(_release_save)

        6    0.000    0.000    0.000    0.000 threading.py:283(_acquire_restore)

        6    0.000    0.000    0.000    0.000 threading.py:286(_is_owned)

        6    0.000    0.000   71.606   11.934 threading.py:295(wait)

        6    0.000    0.000    0.000    0.000 threading.py:562(__init__)

       15    0.000    0.000    0.000    0.000 threading.py:575(is_set)

        6    0.000    0.000   71.607   11.934 threading.py:611(wait)

        3    0.000    0.000    0.000    0.000 threading.py:811(_newname)

        3    0.000    0.000    0.000    0.000 threading.py:856(__init__)

        3    0.000    0.000    0.003    0.001 threading.py:945(start)

       17    0.000    0.000    0.000    0.000 util.py:189(__init__)

       17    0.000    0.000    0.001    0.000 util.py:208(__call__)

       17    0.000    0.000    0.000    0.000 util.py:44(sub_debug)

       29    0.000    0.000    0.000    0.000 util.py:48(debug)

       12    0.000    0.000    0.000    0.000 {built-in method _thread.allocate_lock}

       12    0.000    0.000    0.000    0.000 {built-in method _thread.get_ident}

        3    0.000    0.000    0.000    0.000 {built-in method _thread.start_new_thread}

      118    0.001    0.000    0.001    0.000 {built-in method _winapi.CloseHandle}

        3    0.000    0.000    0.000    0.000 {built-in method _winapi.ConnectNamedPipe}

        3    0.000    0.000    0.000    0.000 {built-in method _winapi.CreateFile}

        3    0.000    0.000    0.000    0.000 {built-in method _winapi.CreateNamedPipe}

       16    0.000    0.000    0.000    0.000 {built-in method _winapi.CreatePipe}

       16    0.068    0.004    0.068    0.004 {built-in method _winapi.CreateProcess}

       96    0.000    0.000    0.000    0.000 {built-in method _winapi.DuplicateHandle}

       96    0.000    0.000    0.000    0.000 {built-in method _winapi.GetCurrentProcess}

       16    0.000    0.000    0.000    0.000 {built-in method _winapi.GetExitCodeProcess}

       64    0.000    0.000    0.000    0.000 {built-in method _winapi.OpenProcess}

        3    0.000    0.000    0.000    0.000 {built-in method _winapi.SetNamedPipeHandleState}

      136    0.276    0.002    0.276    0.002 {built-in method _winapi.WaitForSingleObject}

        4    0.000    0.000    0.000    0.000 {built-in method _winapi.WriteFile}

        3    0.000    0.000    0.000    0.000 {built-in method builtins.divmod}

        1    0.000    0.000   82.392   82.392 {built-in method builtins.exec}

      342    0.000    0.000    0.000    0.000 {built-in method builtins.getattr}

        5    0.000    0.000    0.000    0.000 {built-in method builtins.hasattr}

       55    0.000    0.000    0.000    0.000 {built-in method builtins.isinstance}

       33    0.000    0.000    0.000    0.000 {built-in method builtins.len}

      120    0.000    0.000    0.000    0.000 {built-in method builtins.max}

       45    0.000    0.000    0.000    0.000 {built-in method builtins.next}

       16    0.000    0.000    0.000    0.000 {built-in method io.open}

       48    0.000    0.000    0.000    0.000 {built-in method math.floor}

       16    0.000    0.000    0.000    0.000 {built-in method msvcrt.open_osfhandle}

       16    0.000    0.000    0.000    0.000 {built-in method nt._path_normpath}

        1    0.000    0.000    0.000    0.000 {built-in method nt.cpu_count}

       41    0.000    0.000    0.000    0.000 {built-in method nt.fspath}

       16    0.000    0.000    0.000    0.000 {built-in method nt.getcwd}

      187    0.000    0.000    0.000    0.000 {built-in method nt.getpid}

        3    0.000    0.000    0.000    0.000 {built-in method nt.lstat}

        2    0.000    0.000    0.000    0.000 {built-in method time.time_ns}

        7    0.000    0.000    0.000    0.000 {method 'GetOverlappedResult' of '_winapi.Overlapped' objects}

        6    0.000    0.000    0.000    0.000 {method '__enter__' of '_thread.lock' objects}

       16    0.000    0.000    0.000    0.000 {method '__exit__' of '_io._IOBase' objects}

        3    0.000    0.000    0.000    0.000 {method '__exit__' of '_thread.RLock' objects}

        6    0.000    0.000    0.000    0.000 {method '__exit__' of '_thread.lock' objects}

        1    0.000    0.000    0.000    0.000 {method 'acquire' of '_multiprocessing.SemLock' objects}

       27   71.607    2.652   71.607    2.652 {method 'acquire' of '_thread.lock' objects}

       35    0.000    0.000    0.000    0.000 {method 'add' of 'set' objects}

        6    0.000    0.000    0.000    0.000 {method 'append' of 'collections.deque' objects}

       16    0.000    0.000    0.000    0.000 {method 'append' of 'list' objects}

       52    0.000    0.000    0.000    0.000 {method 'copy' of 'dict' objects}

       16    0.000    0.000    0.000    0.000 {method 'copy' of 'list' objects}

        1    0.000    0.000    0.000    0.000 {method 'digest' of '_hashlib.HASH' objects}

        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

       51    0.000    0.000    0.000    0.000 {method 'discard' of 'set' objects}

       36    0.002    0.000    0.004    0.000 {method 'dump' of '_pickle.Pickler' objects}

        6    0.000    0.000    0.000    0.000 {method 'find' of 'str' objects}

       16    0.000    0.000    0.000    0.000 {method 'get' of 'dict' objects}

        4    0.000    0.000    0.000    0.000 {method 'getbuffer' of '_io.BytesIO' objects}

       19    1.522    0.080    1.522    0.080 {method 'index' of 'list' objects}

       32    0.000    0.000    0.000    0.000 {method 'items' of 'dict' objects}

       54    0.000    0.000    0.000    0.000 {method 'join' of 'str' objects}

        3    0.000    0.000    0.000    0.000 {method 'locked' of '_thread.lock' objects}

        3    0.000    0.000    0.000    0.000 {method 'put' of '_queue.SimpleQueue' objects}

       48    0.000    0.000    0.000    0.000 {method 'random' of '_random.Random' objects}

        9    0.000    0.000    0.000    0.000 {method 'release' of '_thread.lock' objects}

       35    0.000    0.000    0.000    0.000 {method 'replace' of 'str' objects}

       55    0.000    0.000    0.000    0.000 {method 'rpartition' of 'str' objects}

       32    0.000    0.000    0.000    0.000 {method 'startswith' of 'str' objects}

       52    0.000    0.000    0.000    0.000 {method 'update' of 'dict' objects}

        3    0.000    0.000    0.000    0.000 {method 'upper' of 'str' objects}



125250500 84.7045266 None

Enter Password: q

Done

i Process Pool

When thinking of how to fix the early termination problems I was learning more about multiprocessor map functions. That is where I thought more about what I really wanted to do, originally I was just trying to emulate the for loop implementation and have it be the exact same. However I realized that by trying to match the for loop implementation exactly would hinder performance. That then lead me to using imap_unordered instead of map which had the benefit of first being unordered which improved performance since I didn't need things to be ordered. Second is that to my knowledge it returned values as quickly as they were processed which added early termination. This implementation also meant that count would be inconsistent since it all depended on how quickly each core could process data, this is when I also started to return the decoded password instead of just count and time to ensure that the password was correctly found. In terms of performance it is now ~55 seconds for the hardest password in the 500 word dictionary of amongamongamong and was the fastest version for a while and is what was used to estimate the time taken in the initial print. In terms of profiler it is still limited by locks.

i Process Pool Code

def decrypt(password, algorithm, p):

    test = "".join([s for s in p]).encode()

    hash = hashlib.new(algorithm)

    hash.update(test)

    if (hash.digest() == password):

        return test

    return None


def imultiHashAttack(wordLimit: int, words: list, password: bytes, algorithm: str):

    start = time.time_ns()

    count = 0

    func = functools.partial(decrypt, password, algorithm)

    pool = multiprocessing.Pool()

    for i in range(1, wordLimit + 1):

        perms = itertools.product(words, repeat=i)

        for value in pool.imap_unordered(func, perms, chunksize=20000):

            count += 1

            if value != None:

                pool.terminate()

                pool.join()

                return count, (time.time_ns() - start) / 1e9, value.decode()

    pool.close()

    pool.join()

    return None 

cProfile

Longest Password is amongamongamong and will take around 125250500 iterations and around 75.1503 seconds

Enter Password: amongamongamong

Sha256 Hash: 922f052e4cc8f014de935fb51ed139c1e21d091accf6c9d1f89f2c41310e0969

         125348737 function calls in 69.979 seconds


   Ordered by: standard name


   ncalls  tottime  percall  cumtime  percall filename:lineno(function)

       55    0.000    0.000    0.000    0.000 <frozen importlib._bootstrap>:405(parent)

        3    0.000    0.000    0.000    0.000 <frozen ntpath>:107(join)

        6    0.000    0.000    0.000    0.000 <frozen ntpath>:154(splitdrive)

       16    0.000    0.000    0.000    0.000 <frozen ntpath>:538(normpath)

       16    0.000    0.000    0.000    0.000 <frozen ntpath>:87(isabs)

        1    0.000    0.000   69.979   69.979 <string>:1(<module>)

        1   25.197   25.197   69.978   69.978 DicAttack.py:66(imultiHashAttack)

       19    0.000    0.000    0.000    0.000 _weakrefset.py:39(_remove)

       19    0.000    0.000    0.000    0.000 _weakrefset.py:85(add)

        6    0.000    0.000    0.000    0.000 connection.py:118(__init__)

        6    0.000    0.000    0.000    0.000 connection.py:131(__del__)

       67    0.000    0.000    0.000    0.000 connection.py:135(_check_closed)

        3    0.000    0.000    0.000    0.000 connection.py:143(_check_writable)

      128    0.000    0.000    0.000    0.000 connection.py:159(readable)

      128    0.000    0.000    0.000    0.000 connection.py:164(writable)

       64    0.000    0.000    0.000    0.000 connection.py:169(fileno)

        3    0.000    0.000    0.000    0.000 connection.py:182(send_bytes)

        6    0.000    0.000    0.000    0.000 connection.py:277(_close)

        3    0.000    0.000    0.000    0.000 connection.py:284(_send_bytes)

        3    0.000    0.000    0.000    0.000 connection.py:552(Pipe)

        3    0.000    0.000    0.000    0.000 connection.py:70(arbitrary_address)

       64    0.000    0.000    0.001    0.000 connection.py:973(reduce_pipe_connection)

        3    0.000    0.000    0.000    0.000 context.py:110(SimpleQueue)

        1    0.000    0.000    0.084    0.084 context.py:115(Pool)

        6    0.000    0.000    0.000    0.000 context.py:187(get_context)

        3    0.000    0.000    0.000    0.000 context.py:197(get_start_method)

        1    0.000    0.000    0.000    0.000 context.py:237(get_context)

       16    0.000    0.000    0.000    0.000 context.py:253(get_start_method)

       16    0.000    0.000    0.078    0.005 context.py:333(_Popen)

      160    0.000    0.000    0.000    0.000 context.py:365(get_spawning_popen)

       32    0.000    0.000    0.000    0.000 context.py:368(set_spawning_popen)

       64    0.000    0.000    0.000    0.000 context.py:371(assert_spawning)

        3    0.000    0.000    0.000    0.000 context.py:65(Lock)

        1    0.000    0.000    0.000    0.000 pool.py:157(__init__)

       16    0.000    0.000    0.001    0.000 pool.py:179(Process)

        1    0.000    0.000    0.084    0.084 pool.py:183(__init__)

        1    0.000    0.000    0.000    0.000 pool.py:266(__del__)

        1    0.000    0.000    0.000    0.000 pool.py:279(_get_sentinels)

        1    0.000    0.000    0.079    0.079 pool.py:305(_repopulate_pool)

        1    0.000    0.000    0.079    0.079 pool.py:314(_repopulate_pool_static)

        1    0.000    0.000    0.000    0.000 pool.py:345(_setup_queues)

        3    0.000    0.000    0.000    0.000 pool.py:351(_check_running)

        3    0.000    0.000    0.000    0.000 pool.py:425(imap_unordered)

125250503   11.825    0.000   44.571    0.000 pool.py:451(<genexpr>)

        1    0.000    0.000    0.125    0.125 pool.py:654(terminate)

        1    0.000    0.000    0.000    0.000 pool.py:659(join)

        1    0.000    0.000    0.103    0.103 pool.py:671(_help_stuff_finish)

        1    0.000    0.000    0.125    0.125 pool.py:680(_terminate_pool)

        3    0.000    0.000    0.000    0.000 pool.py:839(__init__)

        3    0.000    0.000    0.000    0.000 pool.py:850(__iter__)

     6266    0.089    0.000   32.747    0.005 pool.py:853(next)

      173    0.001    0.000    0.018    0.000 popen_spawn_win32.py:103(wait)

      152    0.000    0.000    0.001    0.000 popen_spawn_win32.py:121(poll)

       16    0.000    0.000    0.003    0.000 popen_spawn_win32.py:124(terminate)

       16    0.000    0.000    0.001    0.000 popen_spawn_win32.py:29(_close_handles)

       16    0.001    0.000    0.077    0.005 popen_spawn_win32.py:45(__init__)

       80    0.000    0.000    0.000    0.000 popen_spawn_win32.py:70(<genexpr>)

       32    0.000    0.000    0.000    0.000 popen_spawn_win32.py:99(duplicate_for_child)

       16    0.000    0.000    0.078    0.005 process.py:110(start)

       16    0.000    0.000    0.003    0.000 process.py:128(terminate)

       21    0.000    0.000    0.018    0.001 process.py:142(join)

       16    0.000    0.000    0.000    0.000 process.py:153(is_alive)

       32    0.000    0.000    0.000    0.000 process.py:189(name)

       16    0.000    0.000    0.000    0.000 process.py:193(name)

       16    0.000    0.000    0.000    0.000 process.py:205(daemon)

       16    0.000    0.000    0.000    0.000 process.py:213(authkey)

       16    0.000    0.000    0.000    0.000 process.py:224(exitcode)

        5    0.000    0.000    0.000    0.000 process.py:234(ident)

       32    0.000    0.000    0.000    0.000 process.py:350(__reduce__)

       35    0.000    0.000    0.000    0.000 process.py:37(current_process)

       16    0.000    0.000    0.001    0.000 process.py:61(_cleanup)

       16    0.000    0.000    0.000    0.000 process.py:80(__init__)

       32    0.000    0.000    0.000    0.000 process.py:94(<genexpr>)

       90    0.000    0.000    0.000    0.000 process.py:99(_check_closed)

        3    0.000    0.000    0.000    0.000 queues.py:339(__init__)

       32    0.000    0.000    0.000    0.000 queues.py:355(__getstate__)

        3    0.000    0.000    0.000    0.000 queues.py:369(put)

        6    0.000    0.000    0.000    0.000 random.py:480(choices)

        6    0.000    0.000    0.000    0.000 random.py:493(<listcomp>)

       64    0.000    0.000    0.001    0.000 reduction.py:106(__init__)

       35    0.000    0.000    0.001    0.000 reduction.py:38(__init__)

        3    0.000    0.000    0.000    0.000 reduction.py:48(dumps)

       32    0.000    0.000    0.005    0.000 reduction.py:58(dump)

       32    0.000    0.000    0.000    0.000 reduction.py:71(duplicate)

       16    0.000    0.000    0.000    0.000 spawn.py:138(_check_not_importing_main)

       16    0.000    0.000    0.001    0.000 spawn.py:160(get_preparation_data)

       32    0.000    0.000    0.000    0.000 spawn.py:45(get_executable)

       16    0.000    0.000    0.001    0.000 spawn.py:83(get_command_line)

       48    0.000    0.000    0.000    0.000 spawn.py:92(<genexpr>)

       16    0.000    0.000    0.000    0.000 subprocess.py:290(_optim_args_from_interpreter_flags)

       16    0.000    0.000    0.000    0.000 subprocess.py:300(_args_from_interpreter_flags)

       32    0.000    0.000    0.000    0.000 synchronize.py:100(__getstate__)

        3    0.000    0.000    0.000    0.000 synchronize.py:121(_make_name)

        3    0.000    0.000    0.000    0.000 synchronize.py:168(__init__)

        3    0.000    0.000    0.000    0.000 synchronize.py:50(__init__)

        3    0.000    0.000    0.000    0.000 synchronize.py:90(_make_methods)

        6    0.000    0.000    0.000    0.000 tempfile.py:143(rng)

        6    0.000    0.000    0.000    0.000 tempfile.py:154(__next__)

        3    0.000    0.000    0.000    0.000 tempfile.py:230(_get_candidate_names)

        3    0.000    0.000    0.000    0.000 tempfile.py:401(mktemp)

        3    0.000    0.000    0.000    0.000 tempfile.py:77(_exists)

        3    0.000    0.000    0.000    0.000 threading.py:1051(_stop)

        6    0.000    0.000    0.000    0.000 threading.py:1087(join)

        8    0.000    0.000    0.000    0.000 threading.py:1125(_wait_for_tstate_lock)

        2    0.000    0.000    0.000    0.000 threading.py:1192(is_alive)

        6    0.000    0.000    0.000    0.000 threading.py:1206(daemon)

        3    0.000    0.000    0.000    0.000 threading.py:1221(daemon)

        3    0.000    0.000    0.000    0.000 threading.py:1324(_make_invoke_excepthook)

       12    0.000    0.000    0.000    0.000 threading.py:1453(current_thread)

        6    0.000    0.000    0.000    0.000 threading.py:243(__init__)

     6269    0.006    0.000    0.010    0.000 threading.py:271(__enter__)

     6269    0.005    0.000    0.006    0.000 threading.py:274(__exit__)

     4666    0.003    0.000    0.004    0.000 threading.py:280(_release_save)

     4666    0.008    0.000    0.012    0.000 threading.py:283(_acquire_restore)

     4666    0.003    0.000    0.006    0.000 threading.py:286(_is_owned)

     4666    0.035    0.000   32.640    0.007 threading.py:295(wait)

        3    0.000    0.000    0.000    0.000 threading.py:562(__init__)

       14    0.000    0.000    0.000    0.000 threading.py:575(is_set)

        3    0.000    0.000    0.003    0.001 threading.py:611(wait)

        3    0.000    0.000    0.000    0.000 threading.py:811(_newname)

        3    0.000    0.000    0.000    0.000 threading.py:856(__init__)

        3    0.000    0.000    0.004    0.001 threading.py:945(start)

       17    0.000    0.000    0.000    0.000 util.py:189(__init__)

       17    0.000    0.000    0.126    0.007 util.py:208(__call__)

       17    0.000    0.000    0.000    0.000 util.py:44(sub_debug)

       34    0.000    0.000    0.000    0.000 util.py:48(debug)

     4672    0.016    0.000    0.016    0.000 {built-in method _thread.allocate_lock}

       12    0.000    0.000    0.000    0.000 {built-in method _thread.get_ident}

        3    0.000    0.000    0.000    0.000 {built-in method _thread.start_new_thread}

      118    0.001    0.000    0.001    0.000 {built-in method _winapi.CloseHandle}

        3    0.000    0.000    0.000    0.000 {built-in method _winapi.ConnectNamedPipe}

        3    0.000    0.000    0.000    0.000 {built-in method _winapi.CreateFile}

        3    0.000    0.000    0.000    0.000 {built-in method _winapi.CreateNamedPipe}

       16    0.000    0.000    0.000    0.000 {built-in method _winapi.CreatePipe}

       16    0.069    0.004    0.069    0.004 {built-in method _winapi.CreateProcess}

       96    0.000    0.000    0.000    0.000 {built-in method _winapi.DuplicateHandle}

       96    0.000    0.000    0.000    0.000 {built-in method _winapi.GetCurrentProcess}

       16    0.000    0.000    0.000    0.000 {built-in method _winapi.GetExitCodeProcess}

       64    0.000    0.000    0.000    0.000 {built-in method _winapi.OpenProcess}

        3    0.000    0.000    0.000    0.000 {built-in method _winapi.SetNamedPipeHandleState}

       16    0.003    0.000    0.003    0.000 {built-in method _winapi.TerminateProcess}

      157    0.018    0.000    0.018    0.000 {built-in method _winapi.WaitForSingleObject}

        3    0.000    0.000    0.000    0.000 {built-in method _winapi.WriteFile}

        1    0.000    0.000   69.979   69.979 {built-in method builtins.exec}

      342    0.000    0.000    0.000    0.000 {built-in method builtins.getattr}

        2    0.000    0.000    0.000    0.000 {built-in method builtins.hasattr}

       55    0.000    0.000    0.000    0.000 {built-in method builtins.isinstance}

       18    0.000    0.000    0.000    0.000 {built-in method builtins.len}

      152    0.000    0.000    0.000    0.000 {built-in method builtins.max}

       45    0.000    0.000    0.000    0.000 {built-in method builtins.next}

       16    0.000    0.000    0.000    0.000 {built-in method io.open}

       48    0.000    0.000    0.000    0.000 {built-in method math.floor}

       16    0.000    0.000    0.000    0.000 {built-in method msvcrt.open_osfhandle}

       16    0.000    0.000    0.000    0.000 {built-in method nt._path_normpath}

        1    0.000    0.000    0.000    0.000 {built-in method nt.cpu_count}

       41    0.000    0.000    0.000    0.000 {built-in method nt.fspath}

       16    0.000    0.000    0.000    0.000 {built-in method nt.getcwd}

      192    0.000    0.000    0.000    0.000 {built-in method nt.getpid}

        3    0.000    0.000    0.000    0.000 {built-in method nt.lstat}

        2    0.000    0.000    0.000    0.000 {built-in method time.time_ns}

        6    0.000    0.000    0.000    0.000 {method 'GetOverlappedResult' of '_winapi.Overlapped' objects}

     6269    0.004    0.000    0.004    0.000 {method '__enter__' of '_thread.lock' objects}

       16    0.000    0.000    0.000    0.000 {method '__exit__' of '_io._IOBase' objects}

        3    0.000    0.000    0.000    0.000 {method '__exit__' of '_thread.RLock' objects}

     6269    0.001    0.000    0.001    0.000 {method '__exit__' of '_thread.lock' objects}

        1    0.103    0.103    0.103    0.103 {method 'acquire' of '_multiprocessing.SemLock' objects}

    18667   32.573    0.002   32.573    0.002 {method 'acquire' of '_thread.lock' objects}

       35    0.000    0.000    0.000    0.000 {method 'add' of 'set' objects}

     4666    0.001    0.000    0.001    0.000 {method 'append' of 'collections.deque' objects}

       16    0.000    0.000    0.000    0.000 {method 'append' of 'list' objects}

       51    0.000    0.000    0.000    0.000 {method 'copy' of 'dict' objects}

       16    0.000    0.000    0.000    0.000 {method 'copy' of 'list' objects}

        1    0.000    0.000    0.000    0.000 {method 'decode' of 'bytes' objects}

        1    0.000    0.000    0.000    0.000 {method 'digest' of '_hashlib.HASH' objects}

        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

       51    0.000    0.000    0.000    0.000 {method 'discard' of 'set' objects}

       35    0.002    0.000    0.004    0.000 {method 'dump' of '_pickle.Pickler' objects}

        6    0.000    0.000    0.000    0.000 {method 'find' of 'str' objects}

       16    0.000    0.000    0.000    0.000 {method 'get' of 'dict' objects}

        3    0.000    0.000    0.000    0.000 {method 'getbuffer' of '_io.BytesIO' objects}

       16    0.000    0.000    0.000    0.000 {method 'index' of 'list' objects}

       32    0.000    0.000    0.000    0.000 {method 'items' of 'dict' objects}

       54    0.000    0.000    0.000    0.000 {method 'join' of 'str' objects}

        3    0.000    0.000    0.000    0.000 {method 'locked' of '_thread.lock' objects}

    10929    0.004    0.000    0.004    0.000 {method 'popleft' of 'collections.deque' objects}

        3    0.000    0.000    0.000    0.000 {method 'put' of '_queue.SimpleQueue' objects}

       48    0.000    0.000    0.000    0.000 {method 'random' of '_random.Random' objects}

     4669    0.001    0.000    0.001    0.000 {method 'release' of '_thread.lock' objects}

       35    0.000    0.000    0.000    0.000 {method 'replace' of 'str' objects}

       55    0.000    0.000    0.000    0.000 {method 'rpartition' of 'str' objects}

       32    0.000    0.000    0.000    0.000 {method 'startswith' of 'str' objects}

       51    0.000    0.000    0.000    0.000 {method 'update' of 'dict' objects}

        3    0.000    0.000    0.000    0.000 {method 'upper' of 'str' objects}



125230500 54.1686588 amongamongamong

Sha512 Hash: 0c0861dc3779cc1e7cc7b1edcdd1864617f3f4c67656724e47c94033ced9f1c0750807a20a7283df8cc52c27d3814fd5200d9ab27d308aaa7df550a70f155249

         125351949 function calls in 74.718 seconds


   Ordered by: standard name


   ncalls  tottime  percall  cumtime  percall filename:lineno(function)

       55    0.000    0.000    0.000    0.000 <frozen importlib._bootstrap>:405(parent)

        3    0.000    0.000    0.000    0.000 <frozen ntpath>:107(join)

        6    0.000    0.000    0.000    0.000 <frozen ntpath>:154(splitdrive)

       16    0.000    0.000    0.000    0.000 <frozen ntpath>:538(normpath)

       16    0.000    0.000    0.000    0.000 <frozen ntpath>:87(isabs)

        1    0.000    0.000   74.718   74.718 <string>:1(<module>)

        1   27.055   27.055   74.717   74.717 DicAttack.py:66(imultiHashAttack)

       19    0.000    0.000    0.000    0.000 _weakrefset.py:39(_remove)

       19    0.000    0.000    0.000    0.000 _weakrefset.py:85(add)

        6    0.000    0.000    0.000    0.000 connection.py:118(__init__)

        6    0.000    0.000    0.000    0.000 connection.py:131(__del__)

       67    0.000    0.000    0.000    0.000 connection.py:135(_check_closed)

        3    0.000    0.000    0.000    0.000 connection.py:143(_check_writable)

      128    0.000    0.000    0.000    0.000 connection.py:159(readable)

      128    0.000    0.000    0.000    0.000 connection.py:164(writable)

       64    0.000    0.000    0.000    0.000 connection.py:169(fileno)

        3    0.000    0.000    0.000    0.000 connection.py:182(send_bytes)

        6    0.000    0.000    0.000    0.000 connection.py:277(_close)

        3    0.000    0.000    0.000    0.000 connection.py:284(_send_bytes)

        3    0.000    0.000    0.000    0.000 connection.py:552(Pipe)

        3    0.000    0.000    0.000    0.000 connection.py:70(arbitrary_address)

       64    0.000    0.000    0.001    0.000 connection.py:973(reduce_pipe_connection)

        3    0.000    0.000    0.001    0.000 context.py:110(SimpleQueue)

        1    0.000    0.000    0.083    0.083 context.py:115(Pool)

        6    0.000    0.000    0.000    0.000 context.py:187(get_context)

        3    0.000    0.000    0.000    0.000 context.py:197(get_start_method)

        1    0.000    0.000    0.000    0.000 context.py:237(get_context)

       16    0.000    0.000    0.000    0.000 context.py:253(get_start_method)

       16    0.000    0.000    0.079    0.005 context.py:333(_Popen)

      160    0.000    0.000    0.000    0.000 context.py:365(get_spawning_popen)

       32    0.000    0.000    0.000    0.000 context.py:368(set_spawning_popen)

       64    0.000    0.000    0.000    0.000 context.py:371(assert_spawning)

        3    0.000    0.000    0.000    0.000 context.py:65(Lock)

        1    0.000    0.000    0.000    0.000 pool.py:157(__init__)

       16    0.000    0.000    0.001    0.000 pool.py:179(Process)

        1    0.000    0.000    0.083    0.083 pool.py:183(__init__)

        1    0.000    0.000    0.000    0.000 pool.py:266(__del__)

        1    0.000    0.000    0.000    0.000 pool.py:279(_get_sentinels)

        1    0.000    0.000    0.081    0.081 pool.py:305(_repopulate_pool)

        1    0.000    0.000    0.081    0.081 pool.py:314(_repopulate_pool_static)

        1    0.000    0.000    0.000    0.000 pool.py:345(_setup_queues)

        3    0.000    0.000    0.000    0.000 pool.py:351(_check_running)

        3    0.000    0.000    0.000    0.000 pool.py:425(imap_unordered)

125250503   12.432    0.000   47.516    0.000 pool.py:451(<genexpr>)

        1    0.000    0.000    0.062    0.062 pool.py:654(terminate)

        1    0.000    0.000    0.000    0.000 pool.py:659(join)

        1    0.000    0.000    0.043    0.043 pool.py:671(_help_stuff_finish)

        1    0.000    0.000    0.062    0.062 pool.py:680(_terminate_pool)

        3    0.000    0.000    0.000    0.000 pool.py:839(__init__)

        3    0.000    0.000    0.000    0.000 pool.py:850(__iter__)

     6266    0.091    0.000   35.084    0.006 pool.py:853(next)

      171    0.000    0.000    0.016    0.000 popen_spawn_win32.py:103(wait)

      152    0.000    0.000    0.001    0.000 popen_spawn_win32.py:121(poll)

       16    0.000    0.000    0.003    0.000 popen_spawn_win32.py:124(terminate)

       16    0.000    0.000    0.001    0.000 popen_spawn_win32.py:29(_close_handles)

       16    0.001    0.000    0.079    0.005 popen_spawn_win32.py:45(__init__)

       80    0.000    0.000    0.000    0.000 popen_spawn_win32.py:70(<genexpr>)

       32    0.000    0.000    0.000    0.000 popen_spawn_win32.py:99(duplicate_for_child)

       16    0.000    0.000    0.080    0.005 process.py:110(start)

       16    0.000    0.000    0.003    0.000 process.py:128(terminate)

       19    0.000    0.000    0.015    0.001 process.py:142(join)

       16    0.000    0.000    0.000    0.000 process.py:153(is_alive)

       32    0.000    0.000    0.000    0.000 process.py:189(name)

       16    0.000    0.000    0.000    0.000 process.py:193(name)

       16    0.000    0.000    0.000    0.000 process.py:205(daemon)

       16    0.000    0.000    0.000    0.000 process.py:213(authkey)

       16    0.000    0.000    0.000    0.000 process.py:224(exitcode)

        3    0.000    0.000    0.000    0.000 process.py:234(ident)

       32    0.000    0.000    0.001    0.000 process.py:350(__reduce__)

       35    0.000    0.000    0.000    0.000 process.py:37(current_process)

       16    0.000    0.000    0.001    0.000 process.py:61(_cleanup)

       16    0.000    0.000    0.000    0.000 process.py:80(__init__)

       32    0.000    0.000    0.000    0.000 process.py:94(<genexpr>)

       86    0.000    0.000    0.000    0.000 process.py:99(_check_closed)

        3    0.000    0.000    0.001    0.000 queues.py:339(__init__)

       32    0.000    0.000    0.000    0.000 queues.py:355(__getstate__)

        3    0.000    0.000    0.000    0.000 queues.py:369(put)

        6    0.000    0.000    0.000    0.000 random.py:480(choices)

        6    0.000    0.000    0.000    0.000 random.py:493(<listcomp>)

       64    0.000    0.000    0.001    0.000 reduction.py:106(__init__)

       35    0.000    0.000    0.001    0.000 reduction.py:38(__init__)

        3    0.000    0.000    0.000    0.000 reduction.py:48(dumps)

       32    0.000    0.000    0.005    0.000 reduction.py:58(dump)

       32    0.000    0.000    0.000    0.000 reduction.py:71(duplicate)

       16    0.000    0.000    0.000    0.000 spawn.py:138(_check_not_importing_main)

       16    0.000    0.000    0.001    0.000 spawn.py:160(get_preparation_data)

       32    0.000    0.000    0.000    0.000 spawn.py:45(get_executable)

       16    0.000    0.000    0.001    0.000 spawn.py:83(get_command_line)

       48    0.000    0.000    0.000    0.000 spawn.py:92(<genexpr>)

       16    0.000    0.000    0.000    0.000 subprocess.py:290(_optim_args_from_interpreter_flags)

       16    0.000    0.000    0.000    0.000 subprocess.py:300(_args_from_interpreter_flags)

       32    0.000    0.000    0.000    0.000 synchronize.py:100(__getstate__)

        3    0.000    0.000    0.000    0.000 synchronize.py:121(_make_name)

        3    0.000    0.000    0.000    0.000 synchronize.py:168(__init__)

        3    0.000    0.000    0.000    0.000 synchronize.py:50(__init__)

        3    0.000    0.000    0.000    0.000 synchronize.py:90(_make_methods)

        6    0.000    0.000    0.000    0.000 tempfile.py:143(rng)

        6    0.000    0.000    0.000    0.000 tempfile.py:154(__next__)

        3    0.000    0.000    0.000    0.000 tempfile.py:230(_get_candidate_names)

        3    0.000    0.000    0.000    0.000 tempfile.py:401(mktemp)

        3    0.000    0.000    0.000    0.000 tempfile.py:77(_exists)

        3    0.000    0.000    0.000    0.000 threading.py:1051(_stop)

        6    0.000    0.000    0.000    0.000 threading.py:1087(join)

        8    0.000    0.000    0.000    0.000 threading.py:1125(_wait_for_tstate_lock)

        2    0.000    0.000    0.000    0.000 threading.py:1192(is_alive)

        6    0.000    0.000    0.000    0.000 threading.py:1206(daemon)

        3    0.000    0.000    0.000    0.000 threading.py:1221(daemon)

        3    0.000    0.000    0.000    0.000 threading.py:1324(_make_invoke_excepthook)

       12    0.000    0.000    0.000    0.000 threading.py:1453(current_thread)

        6    0.000    0.000    0.000    0.000 threading.py:243(__init__)

     6269    0.007    0.000    0.012    0.000 threading.py:271(__enter__)

     6269    0.005    0.000    0.006    0.000 threading.py:274(__exit__)

     4935    0.004    0.000    0.004    0.000 threading.py:280(_release_save)

     4935    0.008    0.000    0.012    0.000 threading.py:283(_acquire_restore)

     4935    0.004    0.000    0.007    0.000 threading.py:286(_is_owned)

     4935    0.046    0.000   34.972    0.007 threading.py:295(wait)

        3    0.000    0.000    0.000    0.000 threading.py:562(__init__)

       14    0.000    0.000    0.000    0.000 threading.py:575(is_set)

        3    0.000    0.000    0.001    0.000 threading.py:611(wait)

        3    0.000    0.000    0.000    0.000 threading.py:811(_newname)

        3    0.000    0.000    0.000    0.000 threading.py:856(__init__)

        3    0.000    0.000    0.001    0.000 threading.py:945(start)

       17    0.000    0.000    0.000    0.000 util.py:189(__init__)

       17    0.000    0.000    0.063    0.004 util.py:208(__call__)

       17    0.000    0.000    0.000    0.000 util.py:44(sub_debug)

       32    0.000    0.000    0.000    0.000 util.py:48(debug)

     4941    0.017    0.000    0.017    0.000 {built-in method _thread.allocate_lock}

       12    0.000    0.000    0.000    0.000 {built-in method _thread.get_ident}

        3    0.000    0.000    0.000    0.000 {built-in method _thread.start_new_thread}

      118    0.001    0.000    0.001    0.000 {built-in method _winapi.CloseHandle}

        3    0.000    0.000    0.000    0.000 {built-in method _winapi.ConnectNamedPipe}

        3    0.000    0.000    0.000    0.000 {built-in method _winapi.CreateFile}

        3    0.000    0.000    0.000    0.000 {built-in method _winapi.CreateNamedPipe}

       16    0.000    0.000    0.000    0.000 {built-in method _winapi.CreatePipe}

       16    0.070    0.004    0.070    0.004 {built-in method _winapi.CreateProcess}

       96    0.000    0.000    0.000    0.000 {built-in method _winapi.DuplicateHandle}

       96    0.000    0.000    0.000    0.000 {built-in method _winapi.GetCurrentProcess}

       16    0.000    0.000    0.000    0.000 {built-in method _winapi.GetExitCodeProcess}

       64    0.000    0.000    0.000    0.000 {built-in method _winapi.OpenProcess}

        3    0.000    0.000    0.000    0.000 {built-in method _winapi.SetNamedPipeHandleState}

       16    0.003    0.000    0.003    0.000 {built-in method _winapi.TerminateProcess}

      155    0.015    0.000    0.015    0.000 {built-in method _winapi.WaitForSingleObject}

        3    0.000    0.000    0.000    0.000 {built-in method _winapi.WriteFile}

        1    0.000    0.000   74.718   74.718 {built-in method builtins.exec}

      342    0.000    0.000    0.000    0.000 {built-in method builtins.getattr}

        2    0.000    0.000    0.000    0.000 {built-in method builtins.hasattr}

       55    0.000    0.000    0.000    0.000 {built-in method builtins.isinstance}

       18    0.000    0.000    0.000    0.000 {built-in method builtins.len}

      152    0.000    0.000    0.000    0.000 {built-in method builtins.max}

       45    0.000    0.000    0.000    0.000 {built-in method builtins.next}

       16    0.000    0.000    0.000    0.000 {built-in method io.open}

       48    0.000    0.000    0.000    0.000 {built-in method math.floor}

       16    0.000    0.000    0.000    0.000 {built-in method msvcrt.open_osfhandle}

       16    0.000    0.000    0.000    0.000 {built-in method nt._path_normpath}

        1    0.000    0.000    0.000    0.000 {built-in method nt.cpu_count}

       41    0.000    0.000    0.000    0.000 {built-in method nt.fspath}

       16    0.000    0.000    0.000    0.000 {built-in method nt.getcwd}

      190    0.000    0.000    0.000    0.000 {built-in method nt.getpid}

        3    0.000    0.000    0.000    0.000 {built-in method nt.lstat}

        2    0.000    0.000    0.000    0.000 {built-in method time.time_ns}

        6    0.000    0.000    0.000    0.000 {method 'GetOverlappedResult' of '_winapi.Overlapped' objects}

     6269    0.005    0.000    0.005    0.000 {method '__enter__' of '_thread.lock' objects}

       16    0.000    0.000    0.000    0.000 {method '__exit__' of '_io._IOBase' objects}

        3    0.000    0.000    0.000    0.000 {method '__exit__' of '_thread.RLock' objects}

     6269    0.001    0.000    0.001    0.000 {method '__exit__' of '_thread.lock' objects}

        1    0.042    0.042    0.042    0.042 {method 'acquire' of '_multiprocessing.SemLock' objects}

    19743   34.890    0.002   34.890    0.002 {method 'acquire' of '_thread.lock' objects}

       35    0.000    0.000    0.000    0.000 {method 'add' of 'set' objects}

     4935    0.001    0.000    0.001    0.000 {method 'append' of 'collections.deque' objects}

       16    0.000    0.000    0.000    0.000 {method 'append' of 'list' objects}

       51    0.000    0.000    0.000    0.000 {method 'copy' of 'dict' objects}

       16    0.000    0.000    0.000    0.000 {method 'copy' of 'list' objects}

        1    0.000    0.000    0.000    0.000 {method 'decode' of 'bytes' objects}

        1    0.000    0.000    0.000    0.000 {method 'digest' of '_hashlib.HASH' objects}

        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

       51    0.000    0.000    0.000    0.000 {method 'discard' of 'set' objects}

       35    0.002    0.000    0.004    0.000 {method 'dump' of '_pickle.Pickler' objects}

        6    0.000    0.000    0.000    0.000 {method 'find' of 'str' objects}

       16    0.000    0.000    0.000    0.000 {method 'get' of 'dict' objects}

        3    0.000    0.000    0.000    0.000 {method 'getbuffer' of '_io.BytesIO' objects}

       16    0.000    0.000    0.000    0.000 {method 'index' of 'list' objects}

       32    0.000    0.000    0.000    0.000 {method 'items' of 'dict' objects}

       54    0.000    0.000    0.000    0.000 {method 'join' of 'str' objects}

        3    0.000    0.000    0.000    0.000 {method 'locked' of '_thread.lock' objects}

    11198    0.005    0.000    0.005    0.000 {method 'popleft' of 'collections.deque' objects}

        3    0.000    0.000    0.000    0.000 {method 'put' of '_queue.SimpleQueue' objects}

       48    0.000    0.000    0.000    0.000 {method 'random' of '_random.Random' objects}

     4938    0.001    0.000    0.001    0.000 {method 'release' of '_thread.lock' objects}

       35    0.000    0.000    0.000    0.000 {method 'replace' of 'str' objects}

       55    0.000    0.000    0.000    0.000 {method 'rpartition' of 'str' objects}

       32    0.000    0.000    0.000    0.000 {method 'startswith' of 'str' objects}

       51    0.000    0.000    0.000    0.000 {method 'update' of 'dict' objects}

        3    0.000    0.000    0.000    0.000 {method 'upper' of 'str' objects}



125250500 57.5101229 amongamongamong

Enter Password: q

Done

Several Processes

Since the bottleneck for a Pool was locks then the idea was to not use a pool but instead make my own. However this ended up making my code very messy since I had to use a queue to store my data instead. Although the code could probably be improved, for example the sleep could be removed, however the current bottleneck is method 'dump' of '_pickle.Pickler' objects which a quick Google search cites Windows being unable to spawn many processes as the problem. In terms of performance it is ~100 seconds for the hardest password in the 500 word dictionary of amongamongamong.

Several Processes Code

def multiDecrypt(perm, password, algorithm, queue):

    count = 0

    for p in perm:

        count += 1

        test = "".join([s for s in p]).encode()

        hash = hashlib.new(algorithm)

        hash.update(test)

        if (hash.digest() == password):

            ret = queue.get()

            ret['item'] = test

            ret['found'] = True

            ret['count'] = ret['count'] + count

            queue.put(ret)

            return

    ret = queue.get()

    ret['count'] = ret['count'] + count

    queue.put(ret)


def multiProcess(wordLimit: int, words: list, password: bytes, algorithm: str):

    start = time.time_ns()

    queue = multiprocessing.Queue()

    queue.put({'item' : -1, 'found' : False, 'count' : 0})

    for i in range(1, wordLimit + 1):

        perms = list(itertools.product(words, repeat=i))

        size = int(len(perms) / multiprocessing.cpu_count())

        processes = []

        for s in range(0, len(perms), size):

            p = multiprocessing.Process(target=multiDecrypt, args=(perms[s : s + size], password, algorithm, queue))

            processes.append(p)

            p.start()

        while True:

            ret = queue.get()

            check = ret['found']

            queue.put(ret)

            if check:

                break

            else:

                check = True

            for p in processes:

                if p.is_alive():

                    check = False

                    break

            if check:

                break

            else:

                time.sleep(1)  

        for p in processes:

            if p.is_alive():

                p.terminate()

            p.join()

        ret =  queue.get()

        if (ret['found']):

            return ret['count'], (time.time_ns() - start) / 1e9, ret['item'].decode()

        else:

            queue.put(ret)

    return None 

cProfile

Longest Password is amongamongamong and will take around 125250500 iterations and around 75.1503 seconds

Enter Password: amongamongamong

Sha256 Hash: 922f052e4cc8f014de935fb51ed139c1e21d091accf6c9d1f89f2c41310e0969

         11943 function calls in 101.580 seconds


   Ordered by: standard name


   ncalls  tottime  percall  cumtime  percall filename:lineno(function)

      151    0.000    0.000    0.001    0.000 <frozen importlib._bootstrap>:405(parent)

        1    0.000    0.000    0.000    0.000 <frozen ntpath>:107(join)

        2    0.000    0.000    0.000    0.000 <frozen ntpath>:154(splitdrive)

       49    0.000    0.000    0.000    0.000 <frozen ntpath>:538(normpath)

       49    0.000    0.000    0.001    0.000 <frozen ntpath>:87(isabs)

        1    5.062    5.062  101.579  101.579 <string>:1(<module>)

        1   13.051   13.051   96.516   96.516 DicAttack.py:101(multiProcess)

       49    0.000    0.000    0.000    0.000 _weakrefset.py:39(_remove)

       50    0.000    0.000    0.000    0.000 _weakrefset.py:85(add)

        2    0.000    0.000    0.000    0.000 connection.py:118(__init__)

      119    0.000    0.000    0.000    0.000 connection.py:135(_check_closed)

       21    0.000    0.000    0.000    0.000 connection.py:139(_check_readable)

      196    0.000    0.000    0.000    0.000 connection.py:159(readable)

      196    0.000    0.000    0.000    0.000 connection.py:164(writable)

       98    0.000    0.000    0.000    0.000 connection.py:169(fileno)

       21    0.000    0.000    0.002    0.000 connection.py:208(recv_bytes)

       21    0.000    0.000    0.001    0.000 connection.py:310(_recv_bytes)

        1    0.000    0.000    0.002    0.002 connection.py:552(Pipe)

        1    0.001    0.001    0.002    0.002 connection.py:70(arbitrary_address)

       98    0.001    0.000    0.003    0.000 connection.py:973(reduce_pipe_connection)

        1    0.000    0.000    0.003    0.003 context.py:100(Queue)

        2    0.000    0.000    0.000    0.000 context.py:187(get_context)

        2    0.000    0.000    0.000    0.000 context.py:197(get_start_method)

       49    0.000    0.000   66.958    1.366 context.py:222(_Popen)

       50    0.000    0.000    0.000    0.000 context.py:237(get_context)

       49    0.000    0.000    0.000    0.000 context.py:253(get_start_method)

       49    0.001    0.000   66.958    1.366 context.py:333(_Popen)

      441    0.000    0.000    0.000    0.000 context.py:365(get_spawning_popen)

       98    0.000    0.000    0.000    0.000 context.py:368(set_spawning_popen)

      147    0.000    0.000    0.000    0.000 context.py:371(assert_spawning)

        3    0.000    0.000    0.000    0.000 context.py:41(cpu_count)

        1    0.000    0.000    0.000    0.000 context.py:65(Lock)

        1    0.000    0.000    0.000    0.000 context.py:85(BoundedSemaphore)

      567    0.001    0.000    0.002    0.000 popen_spawn_win32.py:103(wait)

      518    0.000    0.000    0.002    0.000 popen_spawn_win32.py:121(poll)

       49    0.000    0.000    0.004    0.000 popen_spawn_win32.py:29(_close_handles)

       49    0.003    0.000   66.956    1.366 popen_spawn_win32.py:45(__init__)

      245    0.000    0.000    0.000    0.000 popen_spawn_win32.py:70(<genexpr>)

       98    0.000    0.000    0.000    0.000 popen_spawn_win32.py:99(duplicate_for_child)

       49    1.485    0.030   68.445    1.397 process.py:110(start)

       49    0.000    0.000    0.000    0.000 process.py:142(join)

      292    0.001    0.000    0.002    0.000 process.py:153(is_alive)

       49    0.000    0.000    0.000    0.000 process.py:189(name)

       49    0.000    0.000    0.000    0.000 process.py:213(authkey)

       98    0.001    0.000    0.001    0.000 process.py:350(__reduce__)

      100    0.000    0.000    0.000    0.000 process.py:37(current_process)

       49    0.001    0.000    0.002    0.000 process.py:61(_cleanup)

       49    0.002    0.000    0.002    0.000 process.py:80(__init__)

       98    0.000    0.000    0.000    0.000 process.py:94(<genexpr>)

      390    0.000    0.000    0.000    0.000 process.py:99(_check_closed)

        1    0.000    0.000    0.001    0.001 queues.py:161(_start_thread)

        1    0.000    0.000    0.000    0.000 queues.py:204(_finalize_close)

        1    0.000    0.000    0.003    0.003 queues.py:37(__init__)

       49    0.000    0.000    0.001    0.000 queues.py:57(__getstate__)

        1    0.000    0.000    0.000    0.000 queues.py:71(_reset)

       21    0.000    0.000    0.002    0.000 queues.py:86(put)

       21    0.001    0.000    0.003    0.000 queues.py:98(get)

        3    0.000    0.000    0.000    0.000 random.py:480(choices)

        3    0.000    0.000    0.000    0.000 random.py:493(<listcomp>)

       98    0.000    0.000    0.001    0.000 reduction.py:106(__init__)

       98    0.001    0.000    0.001    0.000 reduction.py:38(__init__)

       98    3.978    0.041   65.231    0.666 reduction.py:58(dump)

       98    0.000    0.000    0.000    0.000 reduction.py:71(duplicate)

       49    0.000    0.000    0.000    0.000 spawn.py:138(_check_not_importing_main)

       49    0.001    0.000    0.003    0.000 spawn.py:160(get_preparation_data)

       98    0.000    0.000    0.000    0.000 spawn.py:45(get_executable)

       49    0.001    0.000    0.002    0.000 spawn.py:83(get_command_line)

      147    0.000    0.000    0.000    0.000 spawn.py:92(<genexpr>)

       49    0.000    0.000    0.000    0.000 subprocess.py:290(_optim_args_from_interpreter_flags)

       49    0.001    0.000    0.001    0.000 subprocess.py:300(_args_from_interpreter_flags)

       98    0.000    0.000    0.001    0.000 synchronize.py:100(__getstate__)

        2    0.000    0.000    0.000    0.000 synchronize.py:121(_make_name)

        1    0.000    0.000    0.000    0.000 synchronize.py:151(__init__)

        1    0.000    0.000    0.000    0.000 synchronize.py:168(__init__)

        2    0.000    0.000    0.000    0.000 synchronize.py:50(__init__)

        2    0.000    0.000    0.000    0.000 synchronize.py:90(_make_methods)

       21    0.000    0.000    0.000    0.000 synchronize.py:94(__enter__)

       21    0.000    0.000    0.000    0.000 synchronize.py:97(__exit__)

        3    0.000    0.000    0.000    0.000 tempfile.py:143(rng)

        3    0.000    0.000    0.001    0.000 tempfile.py:154(__next__)

        1    0.000    0.000    0.000    0.000 tempfile.py:230(_get_candidate_names)

        1    0.000    0.000    0.002    0.002 tempfile.py:401(mktemp)

        1    0.000    0.000    0.000    0.000 tempfile.py:77(_exists)

        1    0.000    0.000    0.000    0.000 threading.py:1206(daemon)

        1    0.000    0.000    0.000    0.000 threading.py:1221(daemon)

        1    0.000    0.000    0.000    0.000 threading.py:1324(_make_invoke_excepthook)

        1    0.000    0.000    0.000    0.000 threading.py:1453(current_thread)

        2    0.000    0.000    0.000    0.000 threading.py:243(__init__)

       23    0.000    0.000    0.000    0.000 threading.py:271(__enter__)

       23    0.000    0.000    0.000    0.000 threading.py:274(__exit__)

        1    0.000    0.000    0.000    0.000 threading.py:280(_release_save)

        1    0.000    0.000    0.000    0.000 threading.py:283(_acquire_restore)

       23    0.000    0.000    0.000    0.000 threading.py:286(_is_owned)

        1    0.000    0.000    0.000    0.000 threading.py:295(wait)

       22    0.000    0.000    0.000    0.000 threading.py:366(notify)

        1    0.000    0.000    0.000    0.000 threading.py:562(__init__)

        2    0.000    0.000    0.000    0.000 threading.py:575(is_set)

        1    0.000    0.000    0.001    0.001 threading.py:611(wait)

        1    0.000    0.000    0.000    0.000 threading.py:856(__init__)

        1    0.000    0.000    0.001    0.001 threading.py:945(start)

       51    0.001    0.000    0.001    0.000 util.py:189(__init__)

       50    0.000    0.000    0.004    0.000 util.py:208(__call__)

       50    0.000    0.000    0.000    0.000 util.py:44(sub_debug)

        6    0.000    0.000    0.000    0.000 util.py:48(debug)

       21    0.000    0.000    0.000    0.000 {built-in method _pickle.loads}

        3    0.000    0.000    0.000    0.000 {built-in method _thread.allocate_lock}

        1    0.000    0.000    0.000    0.000 {built-in method _thread.get_ident}

        1    0.000    0.000    0.000    0.000 {built-in method _thread.start_new_thread}

      245    0.004    0.000    0.004    0.000 {built-in method _winapi.CloseHandle}

        1    0.000    0.000    0.000    0.000 {built-in method _winapi.ConnectNamedPipe}

        1    0.000    0.000    0.000    0.000 {built-in method _winapi.CreateFile}

        1    0.000    0.000    0.000    0.000 {built-in method _winapi.CreateNamedPipe}

       49    0.002    0.000    0.002    0.000 {built-in method _winapi.CreatePipe}

       49    1.711    0.035    1.711    0.035 {built-in method _winapi.CreateProcess}

      196    0.000    0.000    0.000    0.000 {built-in method _winapi.DuplicateHandle}

      196    0.000    0.000    0.000    0.000 {built-in method _winapi.GetCurrentProcess}

       49    0.000    0.000    0.000    0.000 {built-in method _winapi.GetExitCodeProcess}

       98    0.001    0.000    0.001    0.000 {built-in method _winapi.OpenProcess}

       21    0.000    0.000    0.000    0.000 {built-in method _winapi.ReadFile}

        1    0.000    0.000    0.000    0.000 {built-in method _winapi.SetNamedPipeHandleState}

        2    0.000    0.000    0.000    0.000 {built-in method _winapi.WaitForMultipleObjects}

      265    0.001    0.000    0.001    0.000 {built-in method _winapi.WaitForSingleObject}

        1    0.001    0.001  101.580  101.580 {built-in method builtins.exec}

      983    0.001    0.000    0.001    0.000 {built-in method builtins.getattr}

      102    0.000    0.000    0.000    0.000 {built-in method builtins.isinstance}

       11    0.000    0.000    0.000    0.000 {built-in method builtins.len}

      265    0.000    0.000    0.000    0.000 {built-in method builtins.max}

      104    0.000    0.000    0.001    0.000 {built-in method builtins.next}

       49    0.001    0.000    0.001    0.000 {built-in method io.open}

       24    0.000    0.000    0.000    0.000 {built-in method math.floor}

       49    0.000    0.000    0.000    0.000 {built-in method msvcrt.open_osfhandle}

       49    0.000    0.000    0.000    0.000 {built-in method nt._path_normpath}

        3    0.000    0.000    0.000    0.000 {built-in method nt.cpu_count}

      101    0.000    0.000    0.000    0.000 {built-in method nt.fspath}

       49    0.000    0.000    0.000    0.000 {built-in method nt.getcwd}

      692    0.000    0.000    0.000    0.000 {built-in method nt.getpid}

        1    0.000    0.000    0.000    0.000 {built-in method nt.lstat}

       15   15.005    1.000   15.005    1.000 {built-in method time.sleep}

        2    0.000    0.000    0.000    0.000 {built-in method time.time_ns}

       22    0.000    0.000    0.000    0.000 {method 'GetOverlappedResult' of '_winapi.Overlapped' objects}

       21    0.000    0.000    0.000    0.000 {method '__enter__' of '_multiprocessing.SemLock' objects}

       23    0.000    0.000    0.000    0.000 {method '__enter__' of '_thread.lock' objects}

       49    0.002    0.000    0.002    0.000 {method '__exit__' of '_io._IOBase' objects}

       21    0.000    0.000    0.000    0.000 {method '__exit__' of '_multiprocessing.SemLock' objects}

        1    0.000    0.000    0.000    0.000 {method '__exit__' of '_thread.RLock' objects}

       23    0.000    0.000    0.000    0.000 {method '__exit__' of '_thread.lock' objects}

       21    0.000    0.000    0.000    0.000 {method 'acquire' of '_multiprocessing.SemLock' objects}

       26    0.000    0.000    0.000    0.000 {method 'acquire' of '_thread.lock' objects}

       99    0.000    0.000    0.000    0.000 {method 'add' of 'set' objects}

       23    0.000    0.000    0.000    0.000 {method 'append' of 'collections.deque' objects}

       49    0.000    0.000    0.000    0.000 {method 'append' of 'list' objects}

        1    0.000    0.000    0.000    0.000 {method 'clear' of 'collections.deque' objects}

      147    0.000    0.000    0.000    0.000 {method 'copy' of 'dict' objects}

       49    0.000    0.000    0.000    0.000 {method 'copy' of 'list' objects}

        1    0.000    0.000    0.000    0.000 {method 'decode' of 'bytes' objects}

        1    0.000    0.000    0.000    0.000 {method 'digest' of '_hashlib.HASH' objects}

        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

      400    0.000    0.000    0.000    0.000 {method 'discard' of 'set' objects}

       98   61.246    0.625   61.252    0.625 {method 'dump' of '_pickle.Pickler' objects}

        2    0.000    0.000    0.000    0.000 {method 'find' of 'str' objects}

       49    0.000    0.000    0.000    0.000 {method 'get' of 'dict' objects}

       21    0.000    0.000    0.000    0.000 {method 'getbuffer' of '_winapi.Overlapped' objects}

       21    0.000    0.000    0.000    0.000 {method 'getvalue' of '_io.BytesIO' objects}

       49    0.000    0.000    0.000    0.000 {method 'index' of 'list' objects}

       98    0.000    0.000    0.000    0.000 {method 'items' of 'dict' objects}

      150    0.000    0.000    0.001    0.000 {method 'join' of 'str' objects}

       24    0.000    0.000    0.000    0.000 {method 'random' of '_random.Random' objects}

       21    0.000    0.000    0.000    0.000 {method 'release' of '_multiprocessing.SemLock' objects}

       22    0.000    0.000    0.000    0.000 {method 'release' of '_thread.lock' objects}

       21    0.000    0.000    0.000    0.000 {method 'remove' of 'collections.deque' objects}

       50    0.000    0.000    0.000    0.000 {method 'replace' of 'str' objects}

      151    0.000    0.000    0.000    0.000 {method 'rpartition' of 'str' objects}

       98    0.000    0.000    0.000    0.000 {method 'startswith' of 'str' objects}

      147    0.000    0.000    0.000    0.000 {method 'update' of 'dict' objects}

        1    0.000    0.000    0.000    0.000 {method 'upper' of 'str' objects}

       21    0.000    0.000    0.000    0.000 {method 'write' of '_io.BytesIO' objects}



125250500 100.2815231 amongamongamong

Sha512 Hash: 0c0861dc3779cc1e7cc7b1edcdd1864617f3f4c67656724e47c94033ced9f1c0750807a20a7283df8cc52c27d3814fd5200d9ab27d308aaa7df550a70f155249

         12304 function calls in 108.210 seconds


   Ordered by: standard name


   ncalls  tottime  percall  cumtime  percall filename:lineno(function)

      151    0.000    0.000    0.001    0.000 <frozen importlib._bootstrap>:405(parent)

        1    0.000    0.000    0.000    0.000 <frozen ntpath>:107(join)

        2    0.000    0.000    0.000    0.000 <frozen ntpath>:154(splitdrive)

       49    0.000    0.000    0.000    0.000 <frozen ntpath>:538(normpath)

       49    0.000    0.000    0.001    0.000 <frozen ntpath>:87(isabs)

        1    6.644    6.644  108.209  108.209 <string>:1(<module>)

        1   13.012   13.012  101.564  101.564 DicAttack.py:101(multiProcess)

       49    0.000    0.000    0.000    0.000 _weakrefset.py:39(_remove)

       50    0.000    0.000    0.000    0.000 _weakrefset.py:85(add)

        2    0.000    0.000    0.000    0.000 connection.py:118(__init__)

      122    0.000    0.000    0.000    0.000 connection.py:135(_check_closed)

       24    0.000    0.000    0.000    0.000 connection.py:139(_check_readable)

      196    0.000    0.000    0.000    0.000 connection.py:159(readable)

      196    0.000    0.000    0.000    0.000 connection.py:164(writable)

       98    0.000    0.000    0.000    0.000 connection.py:169(fileno)

       24    0.000    0.000    0.002    0.000 connection.py:208(recv_bytes)

       24    0.001    0.000    0.002    0.000 connection.py:310(_recv_bytes)

        1    0.000    0.000    0.001    0.001 connection.py:552(Pipe)

        1    0.000    0.000    0.001    0.001 connection.py:70(arbitrary_address)

       98    0.001    0.000    0.003    0.000 connection.py:973(reduce_pipe_connection)

        1    0.000    0.000    0.002    0.002 context.py:100(Queue)

        2    0.000    0.000    0.000    0.000 context.py:187(get_context)

        2    0.000    0.000    0.000    0.000 context.py:197(get_start_method)

       49    0.000    0.000   68.734    1.403 context.py:222(_Popen)

       50    0.000    0.000    0.000    0.000 context.py:237(get_context)

       49    0.000    0.000    0.000    0.000 context.py:253(get_start_method)

       49    0.001    0.000   68.734    1.403 context.py:333(_Popen)

      441    0.000    0.000    0.001    0.000 context.py:365(get_spawning_popen)

       98    0.000    0.000    0.000    0.000 context.py:368(set_spawning_popen)

      147    0.000    0.000    0.000    0.000 context.py:371(assert_spawning)

        3    0.000    0.000    0.000    0.000 context.py:41(cpu_count)

        1    0.000    0.000    0.000    0.000 context.py:65(Lock)

        1    0.000    0.000    0.000    0.000 context.py:85(BoundedSemaphore)

      614    0.001    0.000    0.002    0.000 popen_spawn_win32.py:103(wait)

      565    0.000    0.000    0.003    0.000 popen_spawn_win32.py:121(poll)

       49    0.000    0.000    0.003    0.000 popen_spawn_win32.py:29(_close_handles)

       49    0.003    0.000   68.732    1.403 popen_spawn_win32.py:45(__init__)

      245    0.000    0.000    0.000    0.000 popen_spawn_win32.py:70(<genexpr>)

       98    0.000    0.000    0.001    0.000 popen_spawn_win32.py:99(duplicate_for_child)

       49    1.795    0.037   70.531    1.439 process.py:110(start)

       49    0.000    0.000    0.000    0.000 process.py:142(join)

      333    0.001    0.000    0.002    0.000 process.py:153(is_alive)

       49    0.000    0.000    0.000    0.000 process.py:189(name)

       49    0.000    0.000    0.000    0.000 process.py:213(authkey)

       98    0.001    0.000    0.002    0.000 process.py:350(__reduce__)

      100    0.000    0.000    0.000    0.000 process.py:37(current_process)

       49    0.001    0.000    0.002    0.000 process.py:61(_cleanup)

       49    0.002    0.000    0.003    0.000 process.py:80(__init__)

       98    0.000    0.000    0.000    0.000 process.py:94(<genexpr>)

      431    0.000    0.000    0.000    0.000 process.py:99(_check_closed)

        1    0.000    0.000    0.001    0.001 queues.py:161(_start_thread)

        1    0.000    0.000    0.000    0.000 queues.py:204(_finalize_close)

        1    0.000    0.000    0.001    0.001 queues.py:37(__init__)

       49    0.000    0.000    0.001    0.000 queues.py:57(__getstate__)

        1    0.000    0.000    0.000    0.000 queues.py:71(_reset)

       24    0.000    0.000    0.002    0.000 queues.py:86(put)

       24    0.001    0.000    0.003    0.000 queues.py:98(get)

        3    0.000    0.000    0.000    0.000 random.py:480(choices)

        3    0.000    0.000    0.000    0.000 random.py:493(<listcomp>)

       98    0.000    0.000    0.002    0.000 reduction.py:106(__init__)

       98    0.001    0.000    0.002    0.000 reduction.py:38(__init__)

       98    4.178    0.043   68.516    0.699 reduction.py:58(dump)

       98    0.000    0.000    0.000    0.000 reduction.py:71(duplicate)

       49    0.000    0.000    0.000    0.000 spawn.py:138(_check_not_importing_main)

       49    0.001    0.000    0.003    0.000 spawn.py:160(get_preparation_data)

       98    0.000    0.000    0.000    0.000 spawn.py:45(get_executable)

       49    0.001    0.000    0.003    0.000 spawn.py:83(get_command_line)

      147    0.000    0.000    0.000    0.000 spawn.py:92(<genexpr>)

       49    0.000    0.000    0.000    0.000 subprocess.py:290(_optim_args_from_interpreter_flags)

       49    0.001    0.000    0.001    0.000 subprocess.py:300(_args_from_interpreter_flags)

       98    0.000    0.000    0.001    0.000 synchronize.py:100(__getstate__)

        2    0.000    0.000    0.000    0.000 synchronize.py:121(_make_name)

        1    0.000    0.000    0.000    0.000 synchronize.py:151(__init__)

        1    0.000    0.000    0.000    0.000 synchronize.py:168(__init__)

        2    0.000    0.000    0.000    0.000 synchronize.py:50(__init__)

        2    0.000    0.000    0.000    0.000 synchronize.py:90(_make_methods)

       24    0.000    0.000    0.000    0.000 synchronize.py:94(__enter__)

       24    0.000    0.000    0.000    0.000 synchronize.py:97(__exit__)

        3    0.000    0.000    0.000    0.000 tempfile.py:143(rng)

        3    0.000    0.000    0.000    0.000 tempfile.py:154(__next__)

        1    0.000    0.000    0.000    0.000 tempfile.py:230(_get_candidate_names)

        1    0.000    0.000    0.001    0.001 tempfile.py:401(mktemp)

        1    0.000    0.000    0.000    0.000 tempfile.py:77(_exists)

        1    0.000    0.000    0.000    0.000 threading.py:1206(daemon)

        1    0.000    0.000    0.000    0.000 threading.py:1221(daemon)

        1    0.000    0.000    0.000    0.000 threading.py:1324(_make_invoke_excepthook)

        1    0.000    0.000    0.000    0.000 threading.py:1453(current_thread)

        2    0.000    0.000    0.000    0.000 threading.py:243(__init__)

       26    0.000    0.000    0.000    0.000 threading.py:271(__enter__)

       26    0.000    0.000    0.000    0.000 threading.py:274(__exit__)

        1    0.000    0.000    0.000    0.000 threading.py:280(_release_save)

        1    0.000    0.000    0.000    0.000 threading.py:283(_acquire_restore)

       26    0.000    0.000    0.000    0.000 threading.py:286(_is_owned)

        1    0.000    0.000    0.000    0.000 threading.py:295(wait)

       25    0.000    0.000    0.001    0.000 threading.py:366(notify)

        1    0.000    0.000    0.000    0.000 threading.py:562(__init__)

        2    0.000    0.000    0.000    0.000 threading.py:575(is_set)

        1    0.000    0.000    0.000    0.000 threading.py:611(wait)

        1    0.000    0.000    0.000    0.000 threading.py:856(__init__)

        1    0.000    0.000    0.001    0.001 threading.py:945(start)

       51    0.001    0.000    0.001    0.000 util.py:189(__init__)

       50    0.000    0.000    0.004    0.000 util.py:208(__call__)

       50    0.000    0.000    0.000    0.000 util.py:44(sub_debug)

        6    0.000    0.000    0.000    0.000 util.py:48(debug)

       24    0.000    0.000    0.000    0.000 {built-in method _pickle.loads}

        3    0.000    0.000    0.000    0.000 {built-in method _thread.allocate_lock}

        1    0.000    0.000    0.000    0.000 {built-in method _thread.get_ident}

        1    0.000    0.000    0.000    0.000 {built-in method _thread.start_new_thread}

      245    0.003    0.000    0.003    0.000 {built-in method _winapi.CloseHandle}

        1    0.000    0.000    0.000    0.000 {built-in method _winapi.ConnectNamedPipe}

        1    0.000    0.000    0.000    0.000 {built-in method _winapi.CreateFile}

        1    0.000    0.000    0.000    0.000 {built-in method _winapi.CreateNamedPipe}

       49    0.002    0.000    0.002    0.000 {built-in method _winapi.CreatePipe}

       49    0.201    0.004    0.201    0.004 {built-in method _winapi.CreateProcess}

      196    0.000    0.000    0.000    0.000 {built-in method _winapi.DuplicateHandle}

      196    0.000    0.000    0.000    0.000 {built-in method _winapi.GetCurrentProcess}

       49    0.000    0.000    0.000    0.000 {built-in method _winapi.GetExitCodeProcess}

       98    0.001    0.000    0.001    0.000 {built-in method _winapi.OpenProcess}

       24    0.001    0.000    0.001    0.000 {built-in method _winapi.ReadFile}

        1    0.000    0.000    0.000    0.000 {built-in method _winapi.SetNamedPipeHandleState}

        3    0.001    0.000    0.001    0.000 {built-in method _winapi.WaitForMultipleObjects}

      274    0.001    0.000    0.001    0.000 {built-in method _winapi.WaitForSingleObject}

        1    0.001    0.001  108.210  108.210 {built-in method builtins.exec}

      983    0.001    0.000    0.001    0.000 {built-in method builtins.getattr}

      102    0.000    0.000    0.000    0.000 {built-in method builtins.isinstance}

       11    0.000    0.000    0.000    0.000 {built-in method builtins.len}

      274    0.000    0.000    0.000    0.000 {built-in method builtins.max}

      104    0.000    0.000    0.000    0.000 {built-in method builtins.next}

       49    0.002    0.000    0.002    0.000 {built-in method io.open}

       24    0.000    0.000    0.000    0.000 {built-in method math.floor}

       49    0.000    0.000    0.000    0.000 {built-in method msvcrt.open_osfhandle}

       49    0.000    0.000    0.000    0.000 {built-in method nt._path_normpath}

        3    0.000    0.000    0.000    0.000 {built-in method nt.cpu_count}

      101    0.000    0.000    0.000    0.000 {built-in method nt.fspath}

       49    0.000    0.000    0.000    0.000 {built-in method nt.getcwd}

      733    0.000    0.000    0.000    0.000 {built-in method nt.getpid}

        1    0.000    0.000    0.000    0.000 {built-in method nt.lstat}

       18   18.006    1.000   18.006    1.000 {built-in method time.sleep}

        2    0.000    0.000    0.000    0.000 {built-in method time.time_ns}

       25    0.000    0.000    0.000    0.000 {method 'GetOverlappedResult' of '_winapi.Overlapped' objects}

       24    0.000    0.000    0.000    0.000 {method '__enter__' of '_multiprocessing.SemLock' objects}

       26    0.000    0.000    0.000    0.000 {method '__enter__' of '_thread.lock' objects}

       49    0.002    0.000    0.002    0.000 {method '__exit__' of '_io._IOBase' objects}

       24    0.000    0.000    0.000    0.000 {method '__exit__' of '_multiprocessing.SemLock' objects}

        1    0.000    0.000    0.000    0.000 {method '__exit__' of '_thread.RLock' objects}

       26    0.000    0.000    0.000    0.000 {method '__exit__' of '_thread.lock' objects}

       24    0.000    0.000    0.000    0.000 {method 'acquire' of '_multiprocessing.SemLock' objects}

       29    0.000    0.000    0.000    0.000 {method 'acquire' of '_thread.lock' objects}

       99    0.000    0.000    0.000    0.000 {method 'add' of 'set' objects}

       26    0.000    0.000    0.000    0.000 {method 'append' of 'collections.deque' objects}

       49    0.000    0.000    0.000    0.000 {method 'append' of 'list' objects}

        1    0.000    0.000    0.000    0.000 {method 'clear' of 'collections.deque' objects}

      147    0.000    0.000    0.000    0.000 {method 'copy' of 'dict' objects}

       49    0.000    0.000    0.000    0.000 {method 'copy' of 'list' objects}

        1    0.000    0.000    0.000    0.000 {method 'decode' of 'bytes' objects}

        1    0.000    0.000    0.000    0.000 {method 'digest' of '_hashlib.HASH' objects}

        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

      438    0.000    0.000    0.000    0.000 {method 'discard' of 'set' objects}

       98   64.331    0.656   64.337    0.657 {method 'dump' of '_pickle.Pickler' objects}

        2    0.000    0.000    0.000    0.000 {method 'find' of 'str' objects}

       49    0.000    0.000    0.000    0.000 {method 'get' of 'dict' objects}

       24    0.000    0.000    0.000    0.000 {method 'getbuffer' of '_winapi.Overlapped' objects}

       24    0.000    0.000    0.000    0.000 {method 'getvalue' of '_io.BytesIO' objects}

       49    0.000    0.000    0.000    0.000 {method 'index' of 'list' objects}

       98    0.000    0.000    0.000    0.000 {method 'items' of 'dict' objects}

      150    0.000    0.000    0.001    0.000 {method 'join' of 'str' objects}

       24    0.000    0.000    0.000    0.000 {method 'random' of '_random.Random' objects}

       24    0.000    0.000    0.000    0.000 {method 'release' of '_multiprocessing.SemLock' objects}

       25    0.000    0.000    0.000    0.000 {method 'release' of '_thread.lock' objects}

       24    0.000    0.000    0.000    0.000 {method 'remove' of 'collections.deque' objects}

       50    0.000    0.000    0.000    0.000 {method 'replace' of 'str' objects}

      151    0.000    0.000    0.000    0.000 {method 'rpartition' of 'str' objects}

       98    0.000    0.000    0.000    0.000 {method 'startswith' of 'str' objects}

      147    0.000    0.000    0.000    0.000 {method 'update' of 'dict' objects}

        1    0.000    0.000    0.000    0.000 {method 'upper' of 'str' objects}

       24    0.000    0.000    0.000    0.000 {method 'write' of '_io.BytesIO' objects}



125250500 97.0823214 amongamongamong

Enter Password: q

Done

Several Threads

Since the bottleneck seemed to be Processes then what if I didn't use Processes but instead Threads. Thus after many iterations I am left with the following code. Although it may not be perfect the longest total time is in the hashing function meaning that my code is taking the longest rather then something else which has happened. For example sleep originally took the longest, that got fixed then _winapi.WaitForMultipleObjects took the longest and when that was fixed it was threading.is_alive. However now it is simply how long it takes to test all permutations. In terms of performance it is ~190 seconds for the hardest password in the 500 word dictionary of amongamongamong.

Several Threads Code

def multiStopDecrypt(perm, password, algorithm, arr, lock, stop, running):

    count = 0

    for p in perm:

        count += 1

        test = "".join([s for s in p]).encode()

        hash = hashlib.new(algorithm)

        hash.update(test)

        if (hash.digest() == password):

            lock.acquire()

            arr[2] = test

            arr[1] = True

            arr[0] = arr[0] + count

            running[0] = running[0] + 1

            lock.release()

            return

    lock.acquire()

    arr[0] = arr[0] + count

    running[0] = running[0] + 1

    lock.release()


def multiThread(wordLimit: int, words: list, password: bytes, algorithm: str):

    start = time.time_ns()

    stop_threads = False

    arr = [0, False, -1]

    lock = threading.Lock()

    for i in range(1, wordLimit + 1):

        perms = list(itertools.product(words, repeat=i))

        size = int(len(perms) / multiprocessing.cpu_count())

        processes = []

        running = [0]

        for s in range(0, len(perms), size):

            p = threading.Thread(target=multiStopDecrypt, args=(perms[s : s + size], password, algorithm, arr, lock, lambda: stop_threads, running))

            processes.append(p)

            p.start()

        while running[0] != len(processes):

            lock.acquire()

            check = arr[1]

            lock.release()

            if check:

                stop_threads = True

                break

        for p in processes:

            p.join()

        if (arr[1]):

            return arr[0], (time.time_ns() - start) / 1e9, arr[2].decode()

    return None 

cProfile

Longest Password is amongamongamong and will take around 125250500 iterations and around 75.1503 seconds

Enter Password: amongamongamong

Sha256 Hash: 922f052e4cc8f014de935fb51ed139c1e21d091accf6c9d1f89f2c41310e0969

         48353595 function calls in 198.989 seconds


   Ordered by: standard name


   ncalls  tottime  percall  cumtime  percall filename:lineno(function)

        1    3.018    3.018  198.988  198.988 <string>:1(<module>)

        1  185.330  185.330  195.970  195.970 DicAttack.py:160(multiThread)

       49    0.000    0.000    0.000    0.000 _weakrefset.py:39(_remove)

       49    0.000    0.000    0.000    0.000 _weakrefset.py:85(add)

        3    0.000    0.000    0.000    0.000 context.py:41(cpu_count)

       49    0.000    0.000    0.000    0.000 threading.py:1051(_stop)

       49    0.000    0.000    3.110    0.063 threading.py:1087(join)

       49    0.000    0.000    3.109    0.063 threading.py:1125(_wait_for_tstate_lock)

       98    0.000    0.000    0.000    0.000 threading.py:1206(daemon)

       49    0.000    0.000    0.000    0.000 threading.py:1324(_make_invoke_excepthook)

       98    0.000    0.000    0.000    0.000 threading.py:1453(current_thread)

       49    0.001    0.000    0.001    0.000 threading.py:243(__init__)

       49    0.000    0.000    0.000    0.000 threading.py:271(__enter__)

       49    0.000    0.000    0.000    0.000 threading.py:274(__exit__)

       49    0.000    0.000    0.000    0.000 threading.py:280(_release_save)

       49    0.000    0.000    0.000    0.000 threading.py:283(_acquire_restore)

       49    0.000    0.000    0.000    0.000 threading.py:286(_is_owned)

       49    0.000    0.000    4.115    0.084 threading.py:295(wait)

       49    0.000    0.000    0.001    0.000 threading.py:562(__init__)

       98    0.000    0.000    0.000    0.000 threading.py:575(is_set)

       49    0.001    0.000    4.116    0.084 threading.py:611(wait)

       49    0.000    0.000    0.000    0.000 threading.py:811(_newname)

       49    0.000    0.000    0.000    0.000 threading.py:829(_maintain_shutdown_locks)

       49    0.000    0.000    0.000    0.000 threading.py:839(<listcomp>)

       49    0.001    0.000    0.003    0.000 threading.py:856(__init__)

       49    0.000    0.000    4.118    0.084 threading.py:945(start)

       99    0.000    0.000    0.000    0.000 {built-in method _thread.allocate_lock}

       98    0.000    0.000    0.000    0.000 {built-in method _thread.get_ident}

       49    0.002    0.000    0.002    0.000 {built-in method _thread.start_new_thread}

        1    0.001    0.001  198.989  198.989 {built-in method builtins.exec}

 16117059    0.750    0.000    0.750    0.000 {built-in method builtins.len}

        3    0.000    0.000    0.000    0.000 {built-in method nt.cpu_count}

        2    0.000    0.000    0.000    0.000 {built-in method time.time_ns}

       49    0.000    0.000    0.000    0.000 {method '__enter__' of '_thread.lock' objects}

       49    0.000    0.000    0.000    0.000 {method '__exit__' of '_thread.RLock' objects}

       98    0.000    0.000    0.000    0.000 {method '__exit__' of '_thread.lock' objects}

 16117296    8.947    0.000    8.947    0.000 {method 'acquire' of '_thread.lock' objects}

       49    0.000    0.000    0.000    0.000 {method 'add' of 'set' objects}

       49    0.000    0.000    0.000    0.000 {method 'append' of 'collections.deque' objects}

       49    0.000    0.000    0.000    0.000 {method 'append' of 'list' objects}

        1    0.000    0.000    0.000    0.000 {method 'decode' of 'bytes' objects}

       49    0.000    0.000    0.000    0.000 {method 'difference_update' of 'set' objects}

        1    0.000    0.000    0.000    0.000 {method 'digest' of '_hashlib.HASH' objects}

        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

       49    0.000    0.000    0.000    0.000 {method 'discard' of 'set' objects}

      116    0.000    0.000    0.000    0.000 {method 'locked' of '_thread.lock' objects}

 16117149    0.934    0.000    0.934    0.000 {method 'release' of '_thread.lock' objects}



125250500 181.8916218 amongamongamong

Sha512 Hash: 0c0861dc3779cc1e7cc7b1edcdd1864617f3f4c67656724e47c94033ced9f1c0750807a20a7283df8cc52c27d3814fd5200d9ab27d308aaa7df550a70f155249

         61462469 function calls in 202.207 seconds


   Ordered by: standard name


   ncalls  tottime  percall  cumtime  percall filename:lineno(function)

        1    2.997    2.997  202.206  202.206 <string>:1(<module>)

        1  188.869  188.869  199.209  199.209 DicAttack.py:160(multiThread)

       49    0.000    0.000    0.000    0.000 _weakrefset.py:39(_remove)

       49    0.000    0.000    0.000    0.000 _weakrefset.py:85(add)

        3    0.000    0.000    0.000    0.000 context.py:41(cpu_count)

       49    0.000    0.000    0.000    0.000 threading.py:1051(_stop)

       49    0.000    0.000    0.474    0.010 threading.py:1087(join)

       49    0.000    0.000    0.473    0.010 threading.py:1125(_wait_for_tstate_lock)

       98    0.000    0.000    0.000    0.000 threading.py:1206(daemon)

       49    0.000    0.000    0.000    0.000 threading.py:1324(_make_invoke_excepthook)

       98    0.000    0.000    0.000    0.000 threading.py:1453(current_thread)

       49    0.001    0.000    0.001    0.000 threading.py:243(__init__)

       49    0.000    0.000    0.000    0.000 threading.py:271(__enter__)

       49    0.000    0.000    0.000    0.000 threading.py:274(__exit__)

       49    0.000    0.000    0.000    0.000 threading.py:280(_release_save)

       49    0.000    0.000    0.000    0.000 threading.py:283(_acquire_restore)

       49    0.000    0.000    0.000    0.000 threading.py:286(_is_owned)

       49    0.001    0.000    4.985    0.102 threading.py:295(wait)

       49    0.000    0.000    0.001    0.000 threading.py:562(__init__)

       98    0.000    0.000    0.000    0.000 threading.py:575(is_set)

       49    0.000    0.000    4.985    0.102 threading.py:611(wait)

       49    0.000    0.000    0.000    0.000 threading.py:811(_newname)

       49    0.000    0.000    0.000    0.000 threading.py:829(_maintain_shutdown_locks)

       49    0.000    0.000    0.000    0.000 threading.py:839(<listcomp>)

       49    0.001    0.000    0.003    0.000 threading.py:856(__init__)

       49    0.000    0.000    4.988    0.102 threading.py:945(start)

       99    0.000    0.000    0.000    0.000 {built-in method _thread.allocate_lock}

       98    0.000    0.000    0.000    0.000 {built-in method _thread.get_ident}

       49    0.002    0.000    0.002    0.000 {built-in method _thread.start_new_thread}

        1    0.001    0.001  202.207  202.207 {built-in method builtins.exec}

 20486674    0.850    0.000    0.850    0.000 {built-in method builtins.len}

        3    0.000    0.000    0.000    0.000 {built-in method nt.cpu_count}

        2    0.000    0.000    0.000    0.000 {built-in method time.time_ns}

       49    0.000    0.000    0.000    0.000 {method '__enter__' of '_thread.lock' objects}

       49    0.000    0.000    0.000    0.000 {method '__exit__' of '_thread.RLock' objects}

       98    0.000    0.000    0.000    0.000 {method '__exit__' of '_thread.lock' objects}

 20486911    8.427    0.000    8.427    0.000 {method 'acquire' of '_thread.lock' objects}

       49    0.000    0.000    0.000    0.000 {method 'add' of 'set' objects}

       49    0.000    0.000    0.000    0.000 {method 'append' of 'collections.deque' objects}

       49    0.000    0.000    0.000    0.000 {method 'append' of 'list' objects}

        1    0.000    0.000    0.000    0.000 {method 'decode' of 'bytes' objects}

       49    0.000    0.000    0.000    0.000 {method 'difference_update' of 'set' objects}

        1    0.000    0.000    0.000    0.000 {method 'digest' of '_hashlib.HASH' objects}

        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

       49    0.000    0.000    0.000    0.000 {method 'discard' of 'set' objects}

      145    0.000    0.000    0.000    0.000 {method 'locked' of '_thread.lock' objects}

 20486764    1.055    0.000    1.055    0.000 {method 'release' of '_thread.lock' objects}



125250500 203.1789594 amongamongamong

Enter Password: q

Done

Several Processors Version 2

Since having several processors and managing them myself seemed the most promising then I went back to that idea. However this time I opted to test pickle's dump on my own which gave me the insight that the thing that was slow was lists. Thus I removed the list and instead passed a itertools.product iterator for the previous permutations and a subsection of the words list. Now in the running function I append each word to the previous permutations to be able to test all permutations. This combined with other smaller optimizations made it so that I finally have a new fastest time of ~30 seconds for the hardest password in the 500 word dictionary of amongamongamong. In terms of profiler everything is roughly the same with no big times, thus the next optimization is probably having a better way of testing if every processor is done since that is around 5 seconds of time.

Several Processors Version 2 Code

def run(perms, arr, algorithm, password, words, lock):

    count = 0

    for p in perms:

        for w in words:

            count += 1

            word = "".join(list(p) + [w]).encode()

            hash = hashlib.new(algorithm)

            hash.update(word)

            if hash.digest() == password:

                with lock:

                    arr[2] = word

                    arr[0] = arr[0] + count

                    arr[1] = True

                return

    with lock:

        arr[0] = arr[0] + count


def multiProcessor2(wordLimit: int, words: list, password: bytes, algorithm: str):

    start = time.time_ns()

    arr = shared_memory.ShareableList([0, False, "\0" * 100])

    lock = multiprocessing.Lock()

    for i in range(1, wordLimit + 1):

        perms = itertools.product(words, repeat=i - 1)

        wordsLen = len(words)

        size = math.ceil(wordsLen / multiprocessing.cpu_count())

        processes = []

        for j in range(0, wordsLen, size):

            p = multiprocessing.Process(target=run,args=[perms, arr, algorithm, password, words[j : j + size], lock])

            p.start()

            processes.append(p)

        while not arr[1] and len(processes) != 0:

            processes = list(filter(lambda p: p.is_alive(), processes))

        for p in processes:

            p.terminate()

            p.join()

        if arr[1]:

            break

    return arr[0], (time.time_ns() - start) / 1e9, arr[2].decode() 

cProfile

Longest Password is amongamongamong and will take around 125250500 iterations and around 75.1503 seconds

Enter Password: amongamongamong

Sha256 Hash: 922f052e4cc8f014de935fb51ed139c1e21d091accf6c9d1f89f2c41310e0969

         25819565 function calls in 24.826 seconds


   Ordered by: standard name


   ncalls  tottime  percall  cumtime  percall filename:lineno(function)

      145    0.000    0.000    0.000    0.000 <frozen importlib._bootstrap>:405(parent)

       48    0.000    0.000    0.000    0.000 <frozen ntpath>:538(normpath)

       48    0.000    0.000    0.001    0.000 <frozen ntpath>:87(isabs)

        1    0.000    0.000   24.826   24.826 <string>:1(<module>)

        1    1.539    1.539   24.824   24.824 MultiProcessor2.py:36(multiProcessor2)

  2772852    1.546    0.000   17.086    0.000 MultiProcessor2.py:50(<lambda>)

       48    0.000    0.000    0.000    0.000 _weakrefset.py:39(_remove)

       48    0.000    0.000    0.000    0.000 _weakrefset.py:85(add)

        1    0.000    0.000    0.000    0.000 context.py:197(get_start_method)

       48    0.000    0.000    3.141    0.065 context.py:222(_Popen)

       49    0.000    0.000    0.000    0.000 context.py:237(get_context)

       48    0.000    0.000    0.000    0.000 context.py:253(get_start_method)

       48    0.001    0.000    3.141    0.065 context.py:333(_Popen)

      240    0.000    0.000    0.000    0.000 context.py:365(get_spawning_popen)

       96    0.000    0.000    0.000    0.000 context.py:368(set_spawning_popen)

       48    0.000    0.000    0.000    0.000 context.py:371(assert_spawning)

        3    0.000    0.000    0.000    0.000 context.py:41(cpu_count)

        1    0.000    0.000    0.000    0.000 context.py:65(Lock)

  2773188    5.008    0.000    8.214    0.000 popen_spawn_win32.py:103(wait)

  2773172    1.587    0.000    9.627    0.000 popen_spawn_win32.py:121(poll)

       16    0.000    0.000    0.004    0.000 popen_spawn_win32.py:124(terminate)

       48    0.000    0.000    0.004    0.000 popen_spawn_win32.py:29(_close_handles)

       48    0.003    0.000    3.139    0.065 popen_spawn_win32.py:45(__init__)

      240    0.000    0.000    0.000    0.000 popen_spawn_win32.py:70(<genexpr>)

       48    0.000    0.000    0.001    0.000 popen_spawn_win32.py:99(duplicate_for_child)

       48    0.001    0.000    3.144    0.066 process.py:110(start)

       16    0.000    0.000    0.004    0.000 process.py:128(terminate)

       16    0.000    0.000    0.173    0.011 process.py:142(join)

  2772852    4.711    0.000   15.540    0.000 process.py:153(is_alive)

       48    0.000    0.000    0.000    0.000 process.py:189(name)

       48    0.000    0.000    0.000    0.000 process.py:213(authkey)

       96    0.001    0.000    0.002    0.000 process.py:350(__reduce__)

       97    0.000    0.000    0.000    0.000 process.py:37(current_process)

       48    0.001    0.000    0.002    0.000 process.py:61(_cleanup)

       48    0.001    0.000    0.002    0.000 process.py:80(__init__)

       96    0.000    0.000    0.000    0.000 process.py:94(<genexpr>)

  2772932    0.682    0.000    0.682    0.000 process.py:99(_check_closed)

        1    0.000    0.000    0.000    0.000 random.py:480(choices)

        1    0.000    0.000    0.000    0.000 random.py:493(<listcomp>)

        1    0.000    0.000    0.000    0.000 random.py:808(randbytes)

       48    0.000    0.000    0.000    0.000 reduction.py:223(_reduce_partial)

       96    0.001    0.000    0.001    0.000 reduction.py:38(__init__)

       96    0.001    0.000    0.012    0.000 reduction.py:58(dump)

       48    0.000    0.000    0.000    0.000 reduction.py:71(duplicate)

        1    0.000    0.000    0.000    0.000 secrets.py:34(token_bytes)

        1    0.000    0.000    0.000    0.000 secrets.py:48(token_hex)

        1    0.000    0.000    0.000    0.000 shared_memory.py:185(__del__)

   573013    0.133    0.000    0.133    0.000 shared_memory.py:204(buf)

       48    0.000    0.000    0.000    0.000 shared_memory.py:209(name)

        1    0.000    0.000    0.000    0.000 shared_memory.py:223(close)

   191002    0.031    0.000    0.031    0.000 shared_memory.py:278(<lambda>)

        1    0.000    0.000    0.000    0.000 shared_memory.py:280(<lambda>)

        3    0.000    0.000    0.000    0.000 shared_memory.py:284(_extract_recreation_code)

        1    0.000    0.000    0.000    0.000 shared_memory.py:298(__init__)

        1    0.000    0.000    0.000    0.000 shared_memory.py:301(<listcomp>)

        4    0.000    0.000    0.000    0.000 shared_memory.py:310(<genexpr>)

        1    0.000    0.000    0.000    0.000 shared_memory.py:319(<listcomp>)

        4    0.000    0.000    0.000    0.000 shared_memory.py:346(<genexpr>)

        4    0.000    0.000    0.000    0.000 shared_memory.py:352(<genexpr>)

   191003    0.608    0.000    1.037    0.000 shared_memory.py:371(_get_packing_format)

   191003    0.402    0.000    0.843    0.000 shared_memory.py:387(_get_back_transform)

        1    0.000    0.000    0.000    0.000 shared_memory.py:40(_make_filename)

   191003    0.736    0.000    2.836    0.000 shared_memory.py:424(__getitem__)

       48    0.000    0.000    0.000    0.000 shared_memory.py:474(__reduce__)

        2    0.000    0.000    0.000    0.000 shared_memory.py:490(_format_size_metainfo)

        2    0.000    0.000    0.000    0.000 shared_memory.py:495(_format_packing_metainfo)

        2    0.000    0.000    0.000    0.000 shared_memory.py:500(_format_back_transform_codes)

   573012    0.195    0.000    0.195    0.000 shared_memory.py:505(_offset_data_start)

   382008    0.271    0.000    0.395    0.000 shared_memory.py:511(_offset_packing_formats)

   191004    0.147    0.000    0.339    0.000 shared_memory.py:515(_offset_back_transform_codes)

        1    0.000    0.000    0.000    0.000 shared_memory.py:75(__init__)

       48    0.000    0.000    0.000    0.000 spawn.py:138(_check_not_importing_main)

       48    0.001    0.000    0.003    0.000 spawn.py:160(get_preparation_data)

       96    0.000    0.000    0.000    0.000 spawn.py:45(get_executable)

       48    0.001    0.000    0.002    0.000 spawn.py:83(get_command_line)

      144    0.000    0.000    0.000    0.000 spawn.py:92(<genexpr>)

       48    0.000    0.000    0.000    0.000 subprocess.py:290(_optim_args_from_interpreter_flags)

       48    0.001    0.000    0.001    0.000 subprocess.py:300(_args_from_interpreter_flags)

       48    0.001    0.000    0.001    0.000 synchronize.py:100(__getstate__)

        1    0.000    0.000    0.000    0.000 synchronize.py:121(_make_name)

        1    0.000    0.000    0.000    0.000 synchronize.py:168(__init__)

        1    0.000    0.000    0.000    0.000 synchronize.py:50(__init__)

        1    0.000    0.000    0.000    0.000 synchronize.py:90(_make_methods)

        1    0.000    0.000    0.000    0.000 tempfile.py:143(rng)

        1    0.000    0.000    0.000    0.000 tempfile.py:154(__next__)

       48    0.001    0.000    0.001    0.000 util.py:189(__init__)

       48    0.000    0.000    0.004    0.000 util.py:208(__call__)

       48    0.000    0.000    0.000    0.000 util.py:44(sub_debug)

        1    0.000    0.000    0.000    0.000 util.py:48(debug)

        1    0.000    0.000    0.000    0.000 {built-in method _struct.calcsize}

        4    0.000    0.000    0.000    0.000 {built-in method _struct.pack_into}

   573009    0.216    0.000    0.216    0.000 {built-in method _struct.unpack_from}

      145    0.004    0.000    0.004    0.000 {built-in method _winapi.CloseHandle}

        1    0.000    0.000    0.000    0.000 {built-in method _winapi.CreateFileMapping}

       48    0.002    0.000    0.002    0.000 {built-in method _winapi.CreatePipe}

       48    0.183    0.004    0.183    0.004 {built-in method _winapi.CreateProcess}

       48    0.000    0.000    0.000    0.000 {built-in method _winapi.DuplicateHandle}

       48    0.000    0.000    0.000    0.000 {built-in method _winapi.GetCurrentProcess}

       49    0.000    0.000    0.000    0.000 {built-in method _winapi.GetExitCodeProcess}

        1    0.000    0.000    0.000    0.000 {built-in method _winapi.GetLastError}

       16    0.004    0.000    0.004    0.000 {built-in method _winapi.TerminateProcess}

  2773179    2.229    0.000    2.229    0.000 {built-in method _winapi.WaitForSingleObject}

        1    0.000    0.000    0.000    0.000 {built-in method binascii.hexlify}

        1    0.000    0.000   24.826   24.826 {built-in method builtins.exec}

      769    0.001    0.000    0.001    0.000 {built-in method builtins.getattr}

      106    0.000    0.000    0.000    0.000 {built-in method builtins.isinstance}

   191008    0.036    0.000    0.036    0.000 {built-in method builtins.len}

  2773163    0.976    0.000    0.976    0.000 {built-in method builtins.max}

       97    0.000    0.000    0.000    0.000 {built-in method builtins.next}

        1    0.000    0.000    0.000    0.000 {built-in method builtins.sum}

       48    0.001    0.000    0.001    0.000 {built-in method io.open}

        3    0.000    0.000    0.000    0.000 {built-in method math.ceil}

        8    0.000    0.000    0.000    0.000 {built-in method math.floor}

       48    0.000    0.000    0.000    0.000 {built-in method msvcrt.open_osfhandle}

       48    0.000    0.000    0.000    0.000 {built-in method nt._path_normpath}

        3    0.000    0.000    0.000    0.000 {built-in method nt.cpu_count}

       96    0.000    0.000    0.000    0.000 {built-in method nt.fspath}

       48    0.000    0.000    0.000    0.000 {built-in method nt.getcwd}

  2773109    0.522    0.000    0.522    0.000 {built-in method nt.getpid}

        1    0.000    0.000    0.000    0.000 {built-in method nt.urandom}

        2    0.000    0.000    0.000    0.000 {built-in method time.time_ns}

       48    2.933    0.061    2.933    0.061 {method '__exit__' of '_io._IOBase' objects}

       96    0.000    0.000    0.000    0.000 {method 'add' of 'set' objects}

       51    0.000    0.000    0.000    0.000 {method 'append' of 'list' objects}

        1    0.000    0.000    0.000    0.000 {method 'close' of 'mmap.mmap' objects}

      144    0.000    0.000    0.000    0.000 {method 'copy' of 'dict' objects}

       48    0.000    0.000    0.000    0.000 {method 'copy' of 'list' objects}

   191005    0.059    0.000    0.059    0.000 {method 'decode' of 'bytes' objects}

        1    0.000    0.000    0.000    0.000 {method 'digest' of '_hashlib.HASH' objects}

        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

      105    0.000    0.000    0.000    0.000 {method 'discard' of 'set' objects}

       96    0.006    0.000    0.010    0.000 {method 'dump' of '_pickle.Pickler' objects}

        4    0.000    0.000    0.000    0.000 {method 'encode' of 'str' objects}

       48    0.000    0.000    0.000    0.000 {method 'get' of 'dict' objects}

       48    0.000    0.000    0.000    0.000 {method 'index' of 'list' objects}

       96    0.000    0.000    0.000    0.000 {method 'items' of 'dict' objects}

      147    0.000    0.000    0.001    0.000 {method 'join' of 'str' objects}

        8    0.000    0.000    0.000    0.000 {method 'random' of '_random.Random' objects}

        1    0.000    0.000    0.000    0.000 {method 'release' of 'memoryview' objects}

       48    0.000    0.000    0.000    0.000 {method 'replace' of 'str' objects}

      145    0.000    0.000    0.000    0.000 {method 'rpartition' of 'str' objects}

   191004    0.037    0.000    0.037    0.000 {method 'rstrip' of 'bytes' objects}

       96    0.000    0.000    0.000    0.000 {method 'startswith' of 'str' objects}

      144    0.000    0.000    0.000    0.000 {method 'update' of 'dict' objects}



61250500 28.7346038 amongamongamong

Sha512 Hash: 0c0861dc3779cc1e7cc7b1edcdd1864617f3f4c67656724e47c94033ced9f1c0750807a20a7283df8cc52c27d3814fd5200d9ab27d308aaa7df550a70f155249

         30864833 function calls in 28.729 seconds


   Ordered by: standard name


   ncalls  tottime  percall  cumtime  percall filename:lineno(function)

      145    0.000    0.000    0.001    0.000 <frozen importlib._bootstrap>:405(parent)

       48    0.000    0.000    0.000    0.000 <frozen ntpath>:538(normpath)

       48    0.000    0.000    0.001    0.000 <frozen ntpath>:87(isabs)

        1    0.000    0.000   28.729   28.729 <string>:1(<module>)

        1    1.806    1.806   28.727   28.727 MultiProcessor2.py:36(multiProcessor2)

  3322970    1.886    0.000   20.672    0.000 MultiProcessor2.py:50(<lambda>)

       48    0.000    0.000    0.000    0.000 _weakrefset.py:39(_remove)

       48    0.000    0.000    0.000    0.000 _weakrefset.py:85(add)

        1    0.000    0.000    0.000    0.000 context.py:197(get_start_method)

       48    0.000    0.000    2.516    0.052 context.py:222(_Popen)

       49    0.000    0.000    0.000    0.000 context.py:237(get_context)

       48    0.000    0.000    0.000    0.000 context.py:253(get_start_method)

       48    0.001    0.000    2.515    0.052 context.py:333(_Popen)

      240    0.000    0.000    0.000    0.000 context.py:365(get_spawning_popen)

       96    0.000    0.000    0.000    0.000 context.py:368(set_spawning_popen)

       48    0.000    0.000    0.000    0.000 context.py:371(assert_spawning)

        3    0.000    0.000    0.000    0.000 context.py:41(cpu_count)

        1    0.000    0.000    0.000    0.000 context.py:65(Lock)

  3323305    6.027    0.000    9.865    0.000 popen_spawn_win32.py:103(wait)

  3323289    1.889    0.000   11.567    0.000 popen_spawn_win32.py:121(poll)

       16    0.000    0.000    0.004    0.000 popen_spawn_win32.py:124(terminate)

       48    0.000    0.000    0.007    0.000 popen_spawn_win32.py:29(_close_handles)

       48    0.004    0.000    2.514    0.052 popen_spawn_win32.py:45(__init__)

      240    0.000    0.000    0.000    0.000 popen_spawn_win32.py:70(<genexpr>)

       48    0.000    0.000    0.001    0.000 popen_spawn_win32.py:99(duplicate_for_child)

       48    0.001    0.000    2.519    0.052 process.py:110(start)

       16    0.000    0.000    0.004    0.000 process.py:128(terminate)

       16    0.000    0.000    0.187    0.012 process.py:142(join)

  3322970    5.737    0.000   18.785    0.000 process.py:153(is_alive)

       48    0.000    0.000    0.000    0.000 process.py:189(name)

       48    0.000    0.000    0.000    0.000 process.py:213(authkey)

       96    0.002    0.000    0.002    0.000 process.py:350(__reduce__)

       97    0.000    0.000    0.000    0.000 process.py:37(current_process)

       48    0.001    0.000    0.002    0.000 process.py:61(_cleanup)

       48    0.001    0.000    0.002    0.000 process.py:80(__init__)

       96    0.000    0.000    0.000    0.000 process.py:94(<genexpr>)

  3323050    0.822    0.000    0.822    0.000 process.py:99(_check_closed)

        1    0.000    0.000    0.000    0.000 random.py:480(choices)

        1    0.000    0.000    0.000    0.000 random.py:493(<listcomp>)

        1    0.000    0.000    0.000    0.000 random.py:808(randbytes)

       48    0.000    0.000    0.000    0.000 reduction.py:223(_reduce_partial)

       96    0.002    0.000    0.002    0.000 reduction.py:38(__init__)

       96    0.001    0.000    0.015    0.000 reduction.py:58(dump)

       48    0.000    0.000    0.001    0.000 reduction.py:71(duplicate)

        1    0.000    0.000    0.000    0.000 secrets.py:34(token_bytes)

        1    0.000    0.000    0.000    0.000 secrets.py:48(token_hex)

        1    0.000    0.000    0.000    0.000 shared_memory.py:185(__del__)

   674749    0.152    0.000    0.152    0.000 shared_memory.py:204(buf)

       48    0.000    0.000    0.000    0.000 shared_memory.py:209(name)

        1    0.000    0.000    0.000    0.000 shared_memory.py:223(close)

   224914    0.064    0.000    0.064    0.000 shared_memory.py:278(<lambda>)

        1    0.000    0.000    0.000    0.000 shared_memory.py:280(<lambda>)

        3    0.000    0.000    0.000    0.000 shared_memory.py:284(_extract_recreation_code)

        1    0.000    0.000    0.001    0.001 shared_memory.py:298(__init__)

        1    0.000    0.000    0.000    0.000 shared_memory.py:301(<listcomp>)

        4    0.000    0.000    0.000    0.000 shared_memory.py:310(<genexpr>)

        1    0.000    0.000    0.000    0.000 shared_memory.py:319(<listcomp>)

        4    0.000    0.000    0.000    0.000 shared_memory.py:346(<genexpr>)

        4    0.000    0.000    0.000    0.000 shared_memory.py:352(<genexpr>)

   224915    0.755    0.000    1.291    0.000 shared_memory.py:371(_get_packing_format)

   224915    0.487    0.000    1.016    0.000 shared_memory.py:387(_get_back_transform)

        1    0.000    0.000    0.000    0.000 shared_memory.py:40(_make_filename)

   224915    0.873    0.000    3.461    0.000 shared_memory.py:424(__getitem__)

       48    0.000    0.000    0.001    0.000 shared_memory.py:474(__reduce__)

        2    0.000    0.000    0.000    0.000 shared_memory.py:490(_format_size_metainfo)

        2    0.000    0.000    0.000    0.000 shared_memory.py:495(_format_packing_metainfo)

        2    0.000    0.000    0.000    0.000 shared_memory.py:500(_format_back_transform_codes)

   674748    0.245    0.000    0.245    0.000 shared_memory.py:505(_offset_data_start)

   449832    0.346    0.000    0.510    0.000 shared_memory.py:511(_offset_packing_formats)

   224916    0.176    0.000    0.414    0.000 shared_memory.py:515(_offset_back_transform_codes)

        1    0.000    0.000    0.000    0.000 shared_memory.py:75(__init__)

       48    0.000    0.000    0.000    0.000 spawn.py:138(_check_not_importing_main)

       48    0.002    0.000    0.003    0.000 spawn.py:160(get_preparation_data)

       96    0.000    0.000    0.000    0.000 spawn.py:45(get_executable)

       48    0.001    0.000    0.003    0.000 spawn.py:83(get_command_line)

      144    0.000    0.000    0.000    0.000 spawn.py:92(<genexpr>)

       48    0.000    0.000    0.000    0.000 subprocess.py:290(_optim_args_from_interpreter_flags)

       48    0.001    0.000    0.001    0.000 subprocess.py:300(_args_from_interpreter_flags)

       48    0.001    0.000    0.002    0.000 synchronize.py:100(__getstate__)

        1    0.000    0.000    0.000    0.000 synchronize.py:121(_make_name)

        1    0.000    0.000    0.000    0.000 synchronize.py:168(__init__)

        1    0.000    0.000    0.000    0.000 synchronize.py:50(__init__)

        1    0.000    0.000    0.000    0.000 synchronize.py:90(_make_methods)

        1    0.000    0.000    0.000    0.000 tempfile.py:143(rng)

        1    0.000    0.000    0.000    0.000 tempfile.py:154(__next__)

       48    0.001    0.000    0.001    0.000 util.py:189(__init__)

       48    0.001    0.000    0.007    0.000 util.py:208(__call__)

       48    0.000    0.000    0.000    0.000 util.py:44(sub_debug)

        1    0.000    0.000    0.000    0.000 util.py:48(debug)

        1    0.000    0.000    0.000    0.000 {built-in method _struct.calcsize}

        4    0.000    0.000    0.000    0.000 {built-in method _struct.pack_into}

   674745    0.249    0.000    0.249    0.000 {built-in method _struct.unpack_from}

      145    0.007    0.000    0.007    0.000 {built-in method _winapi.CloseHandle}

        1    0.000    0.000    0.000    0.000 {built-in method _winapi.CreateFileMapping}

       48    0.002    0.000    0.002    0.000 {built-in method _winapi.CreatePipe}

       48    0.200    0.004    0.200    0.004 {built-in method _winapi.CreateProcess}

       48    0.000    0.000    0.000    0.000 {built-in method _winapi.DuplicateHandle}

       48    0.000    0.000    0.000    0.000 {built-in method _winapi.GetCurrentProcess}

       49    0.000    0.000    0.000    0.000 {built-in method _winapi.GetExitCodeProcess}

        1    0.000    0.000    0.000    0.000 {built-in method _winapi.GetLastError}

       16    0.004    0.000    0.004    0.000 {built-in method _winapi.TerminateProcess}

  3323296    2.686    0.000    2.686    0.000 {built-in method _winapi.WaitForSingleObject}

        1    0.000    0.000    0.000    0.000 {built-in method binascii.hexlify}

        1    0.000    0.000   28.729   28.729 {built-in method builtins.exec}

      769    0.001    0.000    0.001    0.000 {built-in method builtins.getattr}

      106    0.000    0.000    0.000    0.000 {built-in method builtins.isinstance}

   224920    0.069    0.000    0.069    0.000 {built-in method builtins.len}

  3323280    1.151    0.000    1.151    0.000 {built-in method builtins.max}

       97    0.000    0.000    0.000    0.000 {built-in method builtins.next}

        1    0.000    0.000    0.000    0.000 {built-in method builtins.sum}

       48    0.001    0.000    0.001    0.000 {built-in method io.open}

        3    0.000    0.000    0.000    0.000 {built-in method math.ceil}

        8    0.000    0.000    0.000    0.000 {built-in method math.floor}

       48    0.000    0.000    0.000    0.000 {built-in method msvcrt.open_osfhandle}

       48    0.000    0.000    0.000    0.000 {built-in method nt._path_normpath}

        3    0.000    0.000    0.000    0.000 {built-in method nt.cpu_count}

       96    0.000    0.000    0.000    0.000 {built-in method nt.fspath}

       48    0.000    0.000    0.000    0.000 {built-in method nt.getcwd}

  3323227    0.661    0.000    0.661    0.000 {built-in method nt.getpid}

        1    0.000    0.000    0.000    0.000 {built-in method nt.urandom}

        2    0.000    0.000    0.000    0.000 {built-in method time.time_ns}

       48    2.283    0.048    2.283    0.048 {method '__exit__' of '_io._IOBase' objects}

       96    0.000    0.000    0.000    0.000 {method 'add' of 'set' objects}

       51    0.000    0.000    0.000    0.000 {method 'append' of 'list' objects}

        1    0.000    0.000    0.000    0.000 {method 'close' of 'mmap.mmap' objects}

      144    0.000    0.000    0.000    0.000 {method 'copy' of 'dict' objects}

       48    0.000    0.000    0.000    0.000 {method 'copy' of 'list' objects}

   224917    0.071    0.000    0.071    0.000 {method 'decode' of 'bytes' objects}

        1    0.000    0.000    0.000    0.000 {method 'digest' of '_hashlib.HASH' objects}

        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

      105    0.000    0.000    0.000    0.000 {method 'discard' of 'set' objects}

       96    0.008    0.000    0.012    0.000 {method 'dump' of '_pickle.Pickler' objects}

        4    0.000    0.000    0.000    0.000 {method 'encode' of 'str' objects}

       48    0.000    0.000    0.000    0.000 {method 'get' of 'dict' objects}

       48    0.000    0.000    0.000    0.000 {method 'index' of 'list' objects}

       96    0.000    0.000    0.000    0.000 {method 'items' of 'dict' objects}

      147    0.000    0.000    0.001    0.000 {method 'join' of 'str' objects}

        8    0.000    0.000    0.000    0.000 {method 'random' of '_random.Random' objects}

        1    0.000    0.000    0.000    0.000 {method 'release' of 'memoryview' objects}

       48    0.000    0.000    0.000    0.000 {method 'replace' of 'str' objects}

      145    0.000    0.000    0.000    0.000 {method 'rpartition' of 'str' objects}

   224916    0.044    0.000    0.044    0.000 {method 'rstrip' of 'bytes' objects}

       96    0.000    0.000    0.000    0.000 {method 'startswith' of 'str' objects}

      144    0.000    0.000    0.000    0.000 {method 'update' of 'dict' objects}



29250500 33.8736421 amongamongamong

Enter Password: q

Done

Several Processors Version 2 with Events

Since the goal was to remove filtering a bunch then the idea was to have the code wait until a signal that a process ended. Said signal came in the form of a multi processor event which was sent by a process on completion. In terms of performance it takes ~25 seconds for the hardest password in the 500 word dictionary of amongamongamong. However there were some issues, mainly in that the signal was sent slightly before the process properly finished causing me to have a timeout on the wait to prevent the program from halting. This meant that the filter was still running more then it has too as evident by the ~2500 calls to it rather then the theoretical 48.

Several Processors Version 2 with Events Code

def run(perms, arr, algorithm, password, words, lock, event):

    count = 0

    for p in perms:

        for w in words:

            count += 1

            word = "".join(list(p) + [w]).encode()

            hash = hashlib.new(algorithm)

            hash.update(word)

            if hash.digest() == password:

                with lock:

                    arr[2] = word

                    arr[0] = arr[0] + count

                    arr[1] = True

                event.set()

                return

    with lock:

        arr[0] = arr[0] + count

    event.set()


def multiProcessor2(wordLimit: int, words: list, password: bytes, algorithm: str):

    start = time.time_ns()

    arr = shared_memory.ShareableList([0, False, "\0" * 100])

    lock = multiprocessing.Lock()

    event = multiprocessing.Event()

    for i in range(1, wordLimit + 1):

        perms = itertools.product(words, repeat=i - 1)

        wordsLen = len(words)

        size = math.ceil(wordsLen / multiprocessing.cpu_count())

        processes = []

        for j in range(0, wordsLen, size):

            p = multiprocessing.Process(target=run,args=[perms, arr, algorithm, password, words[j : j + size], lock, event])

            p.start()

            processes.append(p)

        while len(processes) != 0:

            event.wait(timeout=0.1)

            event.clear()

            if arr[1]:

                break

            time.sleep(0.01)

            processes = list(filter(lambda p: p.is_alive(), processes))

        for p in processes:

            p.terminate()

            p.join()

        if arr[1]:

            break

    return arr[0], (time.time_ns() - start) / 1e9, arr[2].decode() 

cProfile

Longest Password is amongamongamong and will take around 125250500 iterations and around 33.817635 seconds

Enter Password: amongamongamong

Sha256 Hash: 922f052e4cc8f014de935fb51ed139c1e21d091accf6c9d1f89f2c41310e0969

         35066 function calls in 19.610 seconds


   Ordered by: standard name


   ncalls  tottime  percall  cumtime  percall filename:lineno(function)

      152    0.000    0.000    0.000    0.000 <frozen importlib._bootstrap>:405(parent)

       48    0.000    0.000    0.000    0.000 <frozen ntpath>:538(normpath)

       48    0.000    0.000    0.000    0.000 <frozen ntpath>:87(isabs)

        1    0.000    0.000   19.610   19.610 <string>:1(<module>)

        1    0.019    0.019   19.609   19.609 MultiProcessorEvent.py:38(multiProcessor2)

     2198    0.002    0.000    0.025    0.000 MultiProcessorEvent.py:58(<lambda>)

       48    0.000    0.000    0.000    0.000 _weakrefset.py:39(_remove)

       48    0.000    0.000    0.000    0.000 _weakrefset.py:85(add)

        6    0.000    0.000    0.000    0.000 context.py:187(get_context)

        6    0.000    0.000    0.000    0.000 context.py:197(get_start_method)

       48    0.000    0.000    2.116    0.044 context.py:222(_Popen)

       50    0.000    0.000    0.000    0.000 context.py:237(get_context)

       48    0.000    0.000    0.000    0.000 context.py:253(get_start_method)

       48    0.001    0.000    2.116    0.044 context.py:333(_Popen)

     1008    0.000    0.000    0.001    0.000 context.py:365(get_spawning_popen)

       96    0.000    0.000    0.000    0.000 context.py:368(set_spawning_popen)

      336    0.000    0.000    0.000    0.000 context.py:371(assert_spawning)

        3    0.000    0.000    0.000    0.000 context.py:41(cpu_count)

        2    0.000    0.000    0.000    0.000 context.py:65(Lock)

        1    0.000    0.000    0.000    0.000 context.py:75(Condition)

        4    0.000    0.000    0.000    0.000 context.py:80(Semaphore)

        1    0.000    0.000    0.000    0.000 context.py:90(Event)

     2534    0.008    0.000    0.122    0.000 popen_spawn_win32.py:103(wait)

     2518    0.002    0.000    0.015    0.000 popen_spawn_win32.py:121(poll)

       16    0.000    0.000    0.003    0.000 popen_spawn_win32.py:124(terminate)

       48    0.000    0.000    0.003    0.000 popen_spawn_win32.py:29(_close_handles)

       48    0.002    0.000    2.115    0.044 popen_spawn_win32.py:45(__init__)

      240    0.000    0.000    0.000    0.000 popen_spawn_win32.py:70(<genexpr>)

      288    0.000    0.000    0.001    0.000 popen_spawn_win32.py:99(duplicate_for_child)

       48    0.001    0.000    2.119    0.044 process.py:110(start)

       16    0.000    0.000    0.003    0.000 process.py:128(terminate)

       16    0.000    0.000    0.109    0.007 process.py:142(join)

     2198    0.007    0.000    0.023    0.000 process.py:153(is_alive)

       48    0.000    0.000    0.000    0.000 process.py:189(name)

       48    0.000    0.000    0.000    0.000 process.py:213(authkey)

       96    0.001    0.000    0.001    0.000 process.py:350(__reduce__)

      102    0.000    0.000    0.000    0.000 process.py:37(current_process)

       48    0.000    0.000    0.002    0.000 process.py:61(_cleanup)

       48    0.001    0.000    0.002    0.000 process.py:80(__init__)

       96    0.000    0.000    0.000    0.000 process.py:94(<genexpr>)

     2278    0.001    0.000    0.001    0.000 process.py:99(_check_closed)

        6    0.000    0.000    0.000    0.000 random.py:480(choices)

        6    0.000    0.000    0.000    0.000 random.py:493(<listcomp>)

        1    0.000    0.000    0.000    0.000 random.py:808(randbytes)

       48    0.000    0.000    0.000    0.000 reduction.py:223(_reduce_partial)

       96    0.001    0.000    0.001    0.000 reduction.py:38(__init__)

       96    0.001    0.000    0.014    0.000 reduction.py:58(dump)

      288    0.000    0.000    0.001    0.000 reduction.py:71(duplicate)

        1    0.000    0.000    0.000    0.000 secrets.py:34(token_bytes)

        1    0.000    0.000    0.000    0.000 secrets.py:48(token_hex)

        1    0.000    0.000    0.000    0.000 shared_memory.py:185(__del__)

      451    0.000    0.000    0.000    0.000 shared_memory.py:204(buf)

       48    0.000    0.000    0.000    0.000 shared_memory.py:209(name)

        1    0.000    0.000    0.000    0.000 shared_memory.py:223(close)

      148    0.000    0.000    0.000    0.000 shared_memory.py:278(<lambda>)

        1    0.000    0.000    0.000    0.000 shared_memory.py:280(<lambda>)

        3    0.000    0.000    0.000    0.000 shared_memory.py:284(_extract_recreation_code)

        1    0.000    0.000    0.000    0.000 shared_memory.py:298(__init__)

        1    0.000    0.000    0.000    0.000 shared_memory.py:301(<listcomp>)

        4    0.000    0.000    0.000    0.000 shared_memory.py:310(<genexpr>)

        1    0.000    0.000    0.000    0.000 shared_memory.py:319(<listcomp>)

        4    0.000    0.000    0.000    0.000 shared_memory.py:346(<genexpr>)

        4    0.000    0.000    0.000    0.000 shared_memory.py:352(<genexpr>)

      149    0.001    0.000    0.003    0.000 shared_memory.py:371(_get_packing_format)

      149    0.001    0.000    0.002    0.000 shared_memory.py:387(_get_back_transform)

        1    0.000    0.000    0.000    0.000 shared_memory.py:40(_make_filename)

      149    0.003    0.000    0.008    0.000 shared_memory.py:424(__getitem__)

       48    0.000    0.000    0.000    0.000 shared_memory.py:474(__reduce__)

        2    0.000    0.000    0.000    0.000 shared_memory.py:490(_format_size_metainfo)

        2    0.000    0.000    0.000    0.000 shared_memory.py:495(_format_packing_metainfo)

        2    0.000    0.000    0.000    0.000 shared_memory.py:500(_format_back_transform_codes)

      450    0.000    0.000    0.000    0.000 shared_memory.py:505(_offset_data_start)

      300    0.000    0.000    0.000    0.000 shared_memory.py:511(_offset_packing_formats)

      150    0.000    0.000    0.000    0.000 shared_memory.py:515(_offset_back_transform_codes)

        1    0.000    0.000    0.000    0.000 shared_memory.py:75(__init__)

       48    0.000    0.000    0.000    0.000 spawn.py:138(_check_not_importing_main)

       48    0.001    0.000    0.002    0.000 spawn.py:160(get_preparation_data)

       96    0.000    0.000    0.000    0.000 spawn.py:45(get_executable)

       48    0.000    0.000    0.002    0.000 spawn.py:83(get_command_line)

      144    0.000    0.000    0.000    0.000 spawn.py:92(<genexpr>)

       48    0.000    0.000    0.000    0.000 subprocess.py:290(_optim_args_from_interpreter_flags)

       48    0.001    0.000    0.001    0.000 subprocess.py:300(_args_from_interpreter_flags)

      288    0.001    0.000    0.003    0.000 synchronize.py:100(__getstate__)

        6    0.000    0.000    0.000    0.000 synchronize.py:121(_make_name)

        4    0.000    0.000    0.000    0.000 synchronize.py:132(__init__)

        2    0.000    0.000    0.000    0.000 synchronize.py:168(__init__)

        1    0.000    0.000    0.000    0.000 synchronize.py:219(__init__)

       48    0.000    0.000    0.000    0.000 synchronize.py:226(__getstate__)

      288    0.001    0.000    0.001    0.000 synchronize.py:236(__enter__)

      288    0.001    0.000    0.002    0.000 synchronize.py:239(__exit__)

        1    0.000    0.000    0.000    0.000 synchronize.py:242(_make_methods)

      134    0.004    0.000   14.683    0.110 synchronize.py:254(wait)

        1    0.000    0.000    0.000    0.000 synchronize.py:330(__init__)

      144    0.001    0.000    0.001    0.000 synchronize.py:347(clear)

      144    0.003    0.000   14.689    0.102 synchronize.py:351(wait)

        6    0.000    0.000    0.000    0.000 synchronize.py:50(__init__)

        6    0.000    0.000    0.000    0.000 synchronize.py:90(_make_methods)

      288    0.001    0.000    0.001    0.000 synchronize.py:94(__enter__)

      288    0.000    0.000    0.001    0.000 synchronize.py:97(__exit__)

        6    0.000    0.000    0.000    0.000 tempfile.py:143(rng)

        6    0.000    0.000    0.000    0.000 tempfile.py:154(__next__)

       48    0.001    0.000    0.001    0.000 util.py:189(__init__)

       48    0.000    0.000    0.003    0.000 util.py:208(__call__)

       48    0.000    0.000    0.000    0.000 util.py:44(sub_debug)

        6    0.000    0.000    0.000    0.000 util.py:48(debug)

        1    0.000    0.000    0.000    0.000 {built-in method _struct.calcsize}

        4    0.000    0.000    0.000    0.000 {built-in method _struct.pack_into}

      447    0.001    0.000    0.001    0.000 {built-in method _struct.unpack_from}

      145    0.003    0.000    0.003    0.000 {built-in method _winapi.CloseHandle}

        1    0.000    0.000    0.000    0.000 {built-in method _winapi.CreateFileMapping}

       48    0.001    0.000    0.001    0.000 {built-in method _winapi.CreatePipe}

       48    0.158    0.003    0.158    0.003 {built-in method _winapi.CreateProcess}

      288    0.001    0.000    0.001    0.000 {built-in method _winapi.DuplicateHandle}

      288    0.000    0.000    0.000    0.000 {built-in method _winapi.GetCurrentProcess}

       49    0.000    0.000    0.000    0.000 {built-in method _winapi.GetExitCodeProcess}

        1    0.000    0.000    0.000    0.000 {built-in method _winapi.GetLastError}

       16    0.003    0.000    0.003    0.000 {built-in method _winapi.TerminateProcess}

     2524    0.112    0.000    0.112    0.000 {built-in method _winapi.WaitForSingleObject}

        1    0.000    0.000    0.000    0.000 {built-in method binascii.hexlify}

        1    0.000    0.000   19.610   19.610 {built-in method builtins.exec}

     1542    0.001    0.000    0.001    0.000 {built-in method builtins.getattr}

      106    0.000    0.000    0.000    0.000 {built-in method builtins.isinstance}

      162    0.000    0.000    0.000    0.000 {built-in method builtins.len}

     2508    0.002    0.000    0.002    0.000 {built-in method builtins.max}

      102    0.000    0.000    0.000    0.000 {built-in method builtins.next}

        1    0.000    0.000    0.000    0.000 {built-in method builtins.sum}

       48    0.001    0.000    0.001    0.000 {built-in method io.open}

        3    0.000    0.000    0.000    0.000 {built-in method math.ceil}

       48    0.000    0.000    0.000    0.000 {built-in method math.floor}

       48    0.000    0.000    0.000    0.000 {built-in method msvcrt.open_osfhandle}

       48    0.000    0.000    0.000    0.000 {built-in method nt._path_normpath}

        3    0.000    0.000    0.000    0.000 {built-in method nt.cpu_count}

       96    0.000    0.000    0.000    0.000 {built-in method nt.fspath}

       48    0.000    0.000    0.000    0.000 {built-in method nt.getcwd}

     2460    0.001    0.000    0.001    0.000 {built-in method nt.getpid}

        1    0.000    0.000    0.000    0.000 {built-in method nt.urandom}

      143    2.631    0.018    2.631    0.018 {built-in method time.sleep}

        2    0.000    0.000    0.000    0.000 {built-in method time.time_ns}

      288    0.000    0.000    0.000    0.000 {method '__enter__' of '_multiprocessing.SemLock' objects}

       48    1.933    0.040    1.933    0.040 {method '__exit__' of '_io._IOBase' objects}

      288    0.001    0.000    0.001    0.000 {method '__exit__' of '_multiprocessing.SemLock' objects}

      134    0.000    0.000    0.000    0.000 {method '_count' of '_multiprocessing.SemLock' objects}

      134    0.000    0.000    0.000    0.000 {method '_is_mine' of '_multiprocessing.SemLock' objects}

      700   14.679    0.021   14.679    0.021 {method 'acquire' of '_multiprocessing.SemLock' objects}

       96    0.000    0.000    0.000    0.000 {method 'add' of 'set' objects}

       51    0.000    0.000    0.000    0.000 {method 'append' of 'list' objects}

        1    0.000    0.000    0.000    0.000 {method 'close' of 'mmap.mmap' objects}

      144    0.000    0.000    0.000    0.000 {method 'copy' of 'dict' objects}

       48    0.000    0.000    0.000    0.000 {method 'copy' of 'list' objects}

      151    0.000    0.000    0.000    0.000 {method 'decode' of 'bytes' objects}

        1    0.000    0.000    0.000    0.000 {method 'digest' of '_hashlib.HASH' objects}

        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

      106    0.000    0.000    0.000    0.000 {method 'discard' of 'set' objects}

       96    0.007    0.000    0.012    0.000 {method 'dump' of '_pickle.Pickler' objects}

        4    0.000    0.000    0.000    0.000 {method 'encode' of 'str' objects}

       48    0.000    0.000    0.000    0.000 {method 'get' of 'dict' objects}

       48    0.000    0.000    0.000    0.000 {method 'index' of 'list' objects}

       96    0.000    0.000    0.000    0.000 {method 'items' of 'dict' objects}

      152    0.000    0.000    0.001    0.000 {method 'join' of 'str' objects}

       48    0.000    0.000    0.000    0.000 {method 'random' of '_random.Random' objects}

      433    0.001    0.000    0.001    0.000 {method 'release' of '_multiprocessing.SemLock' objects}

        1    0.000    0.000    0.000    0.000 {method 'release' of 'memoryview' objects}

       48    0.000    0.000    0.000    0.000 {method 'replace' of 'str' objects}

      152    0.000    0.000    0.000    0.000 {method 'rpartition' of 'str' objects}

      150    0.000    0.000    0.000    0.000 {method 'rstrip' of 'bytes' objects}

       96    0.000    0.000    0.000    0.000 {method 'startswith' of 'str' objects}

      144    0.000    0.000    0.000    0.000 {method 'update' of 'dict' objects}



5250500 23.4468787 amongamongamong

Sha512 Hash: 0c0861dc3779cc1e7cc7b1edcdd1864617f3f4c67656724e47c94033ced9f1c0750807a20a7283df8cc52c27d3814fd5200d9ab27d308aaa7df550a70f155249

         40604 function calls in 24.135 seconds


   Ordered by: standard name


   ncalls  tottime  percall  cumtime  percall filename:lineno(function)

      152    0.000    0.000    0.000    0.000 <frozen importlib._bootstrap>:405(parent)

       48    0.000    0.000    0.000    0.000 <frozen ntpath>:538(normpath)

       48    0.000    0.000    0.001    0.000 <frozen ntpath>:87(isabs)

        1    0.000    0.000   24.135   24.135 <string>:1(<module>)

        1    0.021    0.021   24.133   24.133 MultiProcessorEvent.py:38(multiProcessor2)

     2707    0.003    0.000    0.032    0.000 MultiProcessorEvent.py:58(<lambda>)

       48    0.000    0.000    0.000    0.000 _weakrefset.py:39(_remove)

       48    0.000    0.000    0.000    0.000 _weakrefset.py:85(add)

        6    0.000    0.000    0.000    0.000 context.py:187(get_context)

        6    0.000    0.000    0.000    0.000 context.py:197(get_start_method)

       48    0.000    0.000    2.376    0.050 context.py:222(_Popen)

       50    0.000    0.000    0.000    0.000 context.py:237(get_context)

       48    0.000    0.000    0.000    0.000 context.py:253(get_start_method)

       48    0.001    0.000    2.376    0.049 context.py:333(_Popen)

     1008    0.000    0.000    0.001    0.000 context.py:365(get_spawning_popen)

       96    0.000    0.000    0.000    0.000 context.py:368(set_spawning_popen)

      336    0.000    0.000    0.000    0.000 context.py:371(assert_spawning)

        3    0.000    0.000    0.000    0.000 context.py:41(cpu_count)

        2    0.000    0.000    0.000    0.000 context.py:65(Lock)

        1    0.000    0.000    0.000    0.000 context.py:75(Condition)

        4    0.000    0.000    0.000    0.000 context.py:80(Semaphore)

        1    0.000    0.000    0.000    0.000 context.py:90(Event)

     3046    0.010    0.000    0.219    0.000 popen_spawn_win32.py:103(wait)

     3030    0.002    0.000    0.018    0.000 popen_spawn_win32.py:121(poll)

       16    0.000    0.000    0.004    0.000 popen_spawn_win32.py:124(terminate)

       48    0.000    0.000    0.004    0.000 popen_spawn_win32.py:29(_close_handles)

       48    0.003    0.000    2.375    0.049 popen_spawn_win32.py:45(__init__)

      240    0.000    0.000    0.000    0.000 popen_spawn_win32.py:70(<genexpr>)

      288    0.000    0.000    0.001    0.000 popen_spawn_win32.py:99(duplicate_for_child)

       48    0.001    0.000    2.379    0.050 process.py:110(start)

       16    0.000    0.000    0.004    0.000 process.py:128(terminate)

       16    0.000    0.000    0.204    0.013 process.py:142(join)

     2707    0.010    0.000    0.029    0.000 process.py:153(is_alive)

       48    0.000    0.000    0.000    0.000 process.py:189(name)

       48    0.000    0.000    0.000    0.000 process.py:213(authkey)

       96    0.001    0.000    0.002    0.000 process.py:350(__reduce__)

      102    0.000    0.000    0.000    0.000 process.py:37(current_process)

       48    0.001    0.000    0.002    0.000 process.py:61(_cleanup)

       48    0.001    0.000    0.002    0.000 process.py:80(__init__)

       96    0.000    0.000    0.000    0.000 process.py:94(<genexpr>)

     2787    0.002    0.000    0.002    0.000 process.py:99(_check_closed)

        6    0.000    0.000    0.000    0.000 random.py:480(choices)

        6    0.000    0.000    0.000    0.000 random.py:493(<listcomp>)

        1    0.000    0.000    0.000    0.000 random.py:808(randbytes)

       48    0.000    0.000    0.000    0.000 reduction.py:223(_reduce_partial)

       96    0.001    0.000    0.001    0.000 reduction.py:38(__init__)

       96    0.001    0.000    0.015    0.000 reduction.py:58(dump)

      288    0.000    0.000    0.001    0.000 reduction.py:71(duplicate)

        1    0.000    0.000    0.000    0.000 secrets.py:34(token_bytes)

        1    0.000    0.000    0.000    0.000 secrets.py:48(token_hex)

        1    0.000    0.000    0.000    0.000 shared_memory.py:185(__del__)

      547    0.000    0.000    0.000    0.000 shared_memory.py:204(buf)

       48    0.000    0.000    0.000    0.000 shared_memory.py:209(name)

        1    0.000    0.000    0.000    0.000 shared_memory.py:223(close)

      180    0.000    0.000    0.000    0.000 shared_memory.py:278(<lambda>)

        1    0.000    0.000    0.000    0.000 shared_memory.py:280(<lambda>)

        3    0.000    0.000    0.000    0.000 shared_memory.py:284(_extract_recreation_code)

        1    0.000    0.000    0.000    0.000 shared_memory.py:298(__init__)

        1    0.000    0.000    0.000    0.000 shared_memory.py:301(<listcomp>)

        4    0.000    0.000    0.000    0.000 shared_memory.py:310(<genexpr>)

        1    0.000    0.000    0.000    0.000 shared_memory.py:319(<listcomp>)

        4    0.000    0.000    0.000    0.000 shared_memory.py:346(<genexpr>)

        4    0.000    0.000    0.000    0.000 shared_memory.py:352(<genexpr>)

      181    0.002    0.000    0.004    0.000 shared_memory.py:371(_get_packing_format)

      181    0.001    0.000    0.002    0.000 shared_memory.py:387(_get_back_transform)

        1    0.000    0.000    0.000    0.000 shared_memory.py:40(_make_filename)

      181    0.003    0.000    0.009    0.000 shared_memory.py:424(__getitem__)

       48    0.000    0.000    0.000    0.000 shared_memory.py:474(__reduce__)

        2    0.000    0.000    0.000    0.000 shared_memory.py:490(_format_size_metainfo)

        2    0.000    0.000    0.000    0.000 shared_memory.py:495(_format_packing_metainfo)

        2    0.000    0.000    0.000    0.000 shared_memory.py:500(_format_back_transform_codes)

      546    0.001    0.000    0.001    0.000 shared_memory.py:505(_offset_data_start)

      364    0.000    0.000    0.001    0.000 shared_memory.py:511(_offset_packing_formats)

      182    0.000    0.000    0.001    0.000 shared_memory.py:515(_offset_back_transform_codes)

        1    0.000    0.000    0.000    0.000 shared_memory.py:75(__init__)

       48    0.000    0.000    0.000    0.000 spawn.py:138(_check_not_importing_main)

       48    0.001    0.000    0.003    0.000 spawn.py:160(get_preparation_data)

       96    0.000    0.000    0.000    0.000 spawn.py:45(get_executable)

       48    0.001    0.000    0.002    0.000 spawn.py:83(get_command_line)

      144    0.000    0.000    0.000    0.000 spawn.py:92(<genexpr>)

       48    0.000    0.000    0.000    0.000 subprocess.py:290(_optim_args_from_interpreter_flags)

       48    0.001    0.000    0.001    0.000 subprocess.py:300(_args_from_interpreter_flags)

      288    0.001    0.000    0.003    0.000 synchronize.py:100(__getstate__)

        6    0.000    0.000    0.000    0.000 synchronize.py:121(_make_name)

        4    0.000    0.000    0.000    0.000 synchronize.py:132(__init__)

        2    0.000    0.000    0.000    0.000 synchronize.py:168(__init__)

        1    0.000    0.000    0.000    0.000 synchronize.py:219(__init__)

       48    0.000    0.000    0.000    0.000 synchronize.py:226(__getstate__)

      352    0.001    0.000    0.002    0.000 synchronize.py:236(__enter__)

      352    0.001    0.000    0.002    0.000 synchronize.py:239(__exit__)

        1    0.000    0.000    0.000    0.000 synchronize.py:242(_make_methods)

      168    0.005    0.000   18.400    0.110 synchronize.py:254(wait)

        1    0.000    0.000    0.000    0.000 synchronize.py:330(__init__)

      176    0.001    0.000    0.002    0.000 synchronize.py:347(clear)

      176    0.004    0.000   18.408    0.105 synchronize.py:351(wait)

        6    0.000    0.000    0.000    0.000 synchronize.py:50(__init__)

        6    0.000    0.000    0.000    0.000 synchronize.py:90(_make_methods)

      352    0.001    0.000    0.001    0.000 synchronize.py:94(__enter__)

      352    0.001    0.000    0.001    0.000 synchronize.py:97(__exit__)

        6    0.000    0.000    0.000    0.000 tempfile.py:143(rng)

        6    0.000    0.000    0.000    0.000 tempfile.py:154(__next__)

       48    0.001    0.000    0.001    0.000 util.py:189(__init__)

       48    0.000    0.000    0.004    0.000 util.py:208(__call__)

       48    0.000    0.000    0.000    0.000 util.py:44(sub_debug)

        6    0.000    0.000    0.000    0.000 util.py:48(debug)

        1    0.000    0.000    0.000    0.000 {built-in method _struct.calcsize}

        4    0.000    0.000    0.000    0.000 {built-in method _struct.pack_into}

      543    0.001    0.000    0.001    0.000 {built-in method _struct.unpack_from}

      145    0.004    0.000    0.004    0.000 {built-in method _winapi.CloseHandle}

        1    0.000    0.000    0.000    0.000 {built-in method _winapi.CreateFileMapping}

       48    0.002    0.000    0.002    0.000 {built-in method _winapi.CreatePipe}

       48    0.148    0.003    0.148    0.003 {built-in method _winapi.CreateProcess}

      288    0.000    0.000    0.000    0.000 {built-in method _winapi.DuplicateHandle}

      288    0.000    0.000    0.000    0.000 {built-in method _winapi.GetCurrentProcess}

       49    0.000    0.000    0.000    0.000 {built-in method _winapi.GetExitCodeProcess}

        1    0.000    0.000    0.000    0.000 {built-in method _winapi.GetLastError}

       16    0.004    0.000    0.004    0.000 {built-in method _winapi.TerminateProcess}

     3037    0.207    0.000    0.207    0.000 {built-in method _winapi.WaitForSingleObject}

        1    0.000    0.000    0.000    0.000 {built-in method binascii.hexlify}

        1    0.000    0.000   24.135   24.135 {built-in method builtins.exec}

     1542    0.001    0.000    0.001    0.000 {built-in method builtins.getattr}

      106    0.000    0.000    0.000    0.000 {built-in method builtins.isinstance}

      194    0.000    0.000    0.000    0.000 {built-in method builtins.len}

     3021    0.002    0.000    0.002    0.000 {built-in method builtins.max}

      102    0.000    0.000    0.000    0.000 {built-in method builtins.next}

        1    0.000    0.000    0.000    0.000 {built-in method builtins.sum}

       48    0.001    0.000    0.001    0.000 {built-in method io.open}

        3    0.000    0.000    0.000    0.000 {built-in method math.ceil}

       48    0.000    0.000    0.000    0.000 {built-in method math.floor}

       48    0.000    0.000    0.000    0.000 {built-in method msvcrt.open_osfhandle}

       48    0.000    0.000    0.000    0.000 {built-in method nt._path_normpath}

        3    0.000    0.000    0.000    0.000 {built-in method nt.cpu_count}

       96    0.000    0.000    0.000    0.000 {built-in method nt.fspath}

       48    0.000    0.000    0.000    0.000 {built-in method nt.getcwd}

     2969    0.001    0.000    0.001    0.000 {built-in method nt.getpid}

        1    0.000    0.000    0.000    0.000 {built-in method nt.urandom}

      175    3.068    0.018    3.068    0.018 {built-in method time.sleep}

        2    0.000    0.000    0.000    0.000 {built-in method time.time_ns}

      352    0.000    0.000    0.000    0.000 {method '__enter__' of '_multiprocessing.SemLock' objects}

       48    2.199    0.046    2.199    0.046 {method '__exit__' of '_io._IOBase' objects}

      352    0.000    0.000    0.000    0.000 {method '__exit__' of '_multiprocessing.SemLock' objects}

      168    0.000    0.000    0.000    0.000 {method '_count' of '_multiprocessing.SemLock' objects}

      168    0.000    0.000    0.000    0.000 {method '_is_mine' of '_multiprocessing.SemLock' objects}

      864   18.395    0.021   18.395    0.021 {method 'acquire' of '_multiprocessing.SemLock' objects}

       96    0.000    0.000    0.000    0.000 {method 'add' of 'set' objects}

       51    0.000    0.000    0.000    0.000 {method 'append' of 'list' objects}

        1    0.000    0.000    0.000    0.000 {method 'close' of 'mmap.mmap' objects}

      144    0.000    0.000    0.000    0.000 {method 'copy' of 'dict' objects}

       48    0.000    0.000    0.000    0.000 {method 'copy' of 'list' objects}

      183    0.000    0.000    0.000    0.000 {method 'decode' of 'bytes' objects}

        1    0.000    0.000    0.000    0.000 {method 'digest' of '_hashlib.HASH' objects}

        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

      105    0.000    0.000    0.000    0.000 {method 'discard' of 'set' objects}

       96    0.008    0.000    0.013    0.000 {method 'dump' of '_pickle.Pickler' objects}

        4    0.000    0.000    0.000    0.000 {method 'encode' of 'str' objects}

       48    0.000    0.000    0.000    0.000 {method 'get' of 'dict' objects}

       48    0.000    0.000    0.000    0.000 {method 'index' of 'list' objects}

       96    0.000    0.000    0.000    0.000 {method 'items' of 'dict' objects}

      152    0.000    0.000    0.001    0.000 {method 'join' of 'str' objects}

       48    0.000    0.000    0.000    0.000 {method 'random' of '_random.Random' objects}

      532    0.001    0.000    0.001    0.000 {method 'release' of '_multiprocessing.SemLock' objects}

        1    0.000    0.000    0.000    0.000 {method 'release' of 'memoryview' objects}

       48    0.000    0.000    0.000    0.000 {method 'replace' of 'str' objects}

      152    0.000    0.000    0.000    0.000 {method 'rpartition' of 'str' objects}

      182    0.000    0.000    0.000    0.000 {method 'rstrip' of 'bytes' objects}

       96    0.000    0.000    0.000    0.000 {method 'startswith' of 'str' objects}

      144    0.000    0.000    0.000    0.000 {method 'update' of 'dict' objects}



5250500 26.1561529 amongamongamong

Enter Password: q

Done

Several Processors Version 2 with Pipes

To solve the previous issues I switched from events to pipes which unlike the events, at least to my knowledge, have a buffer so they can store how much data was sent. This solved the issue of what if 2 processors send a event before the event was cleared. I also realized that due to terminating processes my count was wrong in that it wasn't a accurate representation of how many comparisons I did. This is due to me only adding my count at the end of the process. Which of course only happens when the process finishes, which terminate doesn't do. Thus I resolved this issue by using events and threads to signal when a process should end and then only join them rather then terminate them, this also removed the need to filter processes which further improved performance.  In terms of performance it takes ~22 seconds for the hardest password in the 500 word dictionary of amongamongamong. Through the cProfiler we see that the most time is spent on waiting indicating that we should now look at the processor code to see if it can be optimized.

Several Processors Version 2 with Pipes Code

class CancellationToken:

   def __init__(self):

       self.is_cancelled = False


   def cancel(self):

       self.is_cancelled = True


def wait(event, token):

    event.wait()

    token.cancel()


def run(perms, arr, algorithm, password, words, lock, conn, event):

    count = 0

    token = CancellationToken()

    thread = threading.Thread(target=wait, args=[event, token])

    thread.start()

    for p in perms:

        for w in words:

            count += 1

            word = "".join(list(p) + [w]).encode()

            hash = hashlib.new(algorithm)

            hash.update(word)

            if hash.digest() == password:

                event.set()

                with lock:

                    arr[2] = word

                    arr[1] = True

            elif token.is_cancelled: break

        if token.is_cancelled: break

    with lock:

        arr[0] = arr[0] + count

        conn.send_bytes(b'\x00')

    thread.join()



def multiProcessor2(wordLimit: int, words: list, password: bytes, algorithm: str):

    start = time.time_ns()

    arr = shared_memory.ShareableList([0, False, "\0" * 100])

    lock = multiprocessing.Lock()

    recv, send = multiprocessing.Pipe()

    event = multiprocessing.Event()

    for i in range(1, wordLimit + 1):

        perms = itertools.product(words, repeat=i - 1)

        wordsLen = len(words)

        size = math.ceil(wordsLen / multiprocessing.cpu_count())

        processes = []

        for j in range(0, wordsLen, size):

            p = multiprocessing.Process(target=run,args=[perms, arr, algorithm, password, words[j : j + size], lock, send, event])

            p.start()

            processes.append(p)


        completed = 0

        while completed != len(processes):

            recv.recv_bytes()

            if arr[1]:

                break

            completed += 1


        event.set()

        for p in processes:

            p.join()

        event.clear()

        if arr[1]:

            break

    recv.close()

    send.close()

    return arr[0], (time.time_ns() - start) / 1e9, arr[2].decode() 

cProfile

Longest Password is amongamongamong and will take around 86188000 iterations and around 21.55 seconds

Enter Password: amongamongamong

Sha256 Hash: 922f052e4cc8f014de935fb51ed139c1e21d091accf6c9d1f89f2c41310e0969

         13117 function calls in 20.362 seconds


   Ordered by: standard name


   ncalls  tottime  percall  cumtime  percall filename:lineno(function)

      153    0.000    0.000    0.000    0.000 <frozen importlib._bootstrap>:405(parent)

        1    0.000    0.000    0.000    0.000 <frozen ntpath>:107(join)

        2    0.000    0.000    0.000    0.000 <frozen ntpath>:154(splitdrive)

       48    0.000    0.000    0.000    0.000 <frozen ntpath>:538(normpath)

       48    0.000    0.000    0.000    0.000 <frozen ntpath>:87(isabs)

        1    0.000    0.000   20.362   20.362 <string>:1(<module>)

        1    0.001    0.001   20.361   20.361 MultiProcessorPipe.py:51(multiProcessor2)

       48    0.000    0.000    0.000    0.000 _weakrefset.py:39(_remove)

       48    0.000    0.000    0.000    0.000 _weakrefset.py:85(add)

        2    0.000    0.000    0.000    0.000 connection.py:118(__init__)

        2    0.000    0.000    0.000    0.000 connection.py:131(__del__)

       81    0.000    0.000    0.000    0.000 connection.py:135(_check_closed)

       33    0.000    0.000    0.000    0.000 connection.py:139(_check_readable)

       96    0.000    0.000    0.000    0.000 connection.py:159(readable)

       96    0.000    0.000    0.000    0.000 connection.py:164(writable)

       48    0.000    0.000    0.000    0.000 connection.py:169(fileno)

        2    0.000    0.000    0.000    0.000 connection.py:174(close)

       33    0.000    0.000   17.481    0.530 connection.py:208(recv_bytes)

        2    0.000    0.000    0.000    0.000 connection.py:277(_close)

       33    0.001    0.000   17.481    0.530 connection.py:310(_recv_bytes)

        1    0.000    0.000    0.000    0.000 connection.py:552(Pipe)

        1    0.000    0.000    0.000    0.000 connection.py:70(arbitrary_address)

       48    0.000    0.000    0.001    0.000 connection.py:973(reduce_pipe_connection)

        6    0.000    0.000    0.000    0.000 context.py:187(get_context)

        6    0.000    0.000    0.000    0.000 context.py:197(get_start_method)

       48    0.000    0.000    2.009    0.042 context.py:222(_Popen)

       50    0.000    0.000    0.000    0.000 context.py:237(get_context)

       48    0.000    0.000    0.000    0.000 context.py:253(get_start_method)

       48    0.001    0.000    2.009    0.042 context.py:333(_Popen)

     1008    0.000    0.000    0.000    0.000 context.py:365(get_spawning_popen)

       96    0.000    0.000    0.000    0.000 context.py:368(set_spawning_popen)

      336    0.000    0.000    0.000    0.000 context.py:371(assert_spawning)

        3    0.000    0.000    0.000    0.000 context.py:41(cpu_count)

        1    0.000    0.000    0.000    0.000 context.py:60(Pipe)

        2    0.000    0.000    0.000    0.000 context.py:65(Lock)

        1    0.000    0.000    0.000    0.000 context.py:75(Condition)

        4    0.000    0.000    0.000    0.000 context.py:80(Semaphore)

        1    0.000    0.000    0.000    0.000 context.py:90(Event)

      408    0.001    0.000    0.629    0.002 popen_spawn_win32.py:103(wait)

      360    0.000    0.000    0.001    0.000 popen_spawn_win32.py:121(poll)

       48    0.000    0.000    0.002    0.000 popen_spawn_win32.py:29(_close_handles)

       48    0.002    0.000    2.008    0.042 popen_spawn_win32.py:45(__init__)

      240    0.000    0.000    0.000    0.000 popen_spawn_win32.py:70(<genexpr>)

      288    0.000    0.000    0.001    0.000 popen_spawn_win32.py:99(duplicate_for_child)

       48    0.001    0.000    2.012    0.042 process.py:110(start)

       48    0.000    0.000    0.628    0.013 process.py:142(join)

       48    0.000    0.000    0.000    0.000 process.py:189(name)

       48    0.000    0.000    0.000    0.000 process.py:213(authkey)

       96    0.001    0.000    0.001    0.000 process.py:350(__reduce__)

      102    0.000    0.000    0.000    0.000 process.py:37(current_process)

       48    0.000    0.000    0.002    0.000 process.py:61(_cleanup)

       48    0.001    0.000    0.001    0.000 process.py:80(__init__)

       96    0.000    0.000    0.000    0.000 process.py:94(<genexpr>)

       96    0.000    0.000    0.000    0.000 process.py:99(_check_closed)

        7    0.000    0.000    0.000    0.000 random.py:480(choices)

        7    0.000    0.000    0.000    0.000 random.py:493(<listcomp>)

        1    0.000    0.000    0.000    0.000 random.py:808(randbytes)

       48    0.000    0.000    0.001    0.000 reduction.py:106(__init__)

       48    0.000    0.000    0.000    0.000 reduction.py:223(_reduce_partial)

       96    0.001    0.000    0.001    0.000 reduction.py:38(__init__)

       96    0.001    0.000    0.014    0.000 reduction.py:58(dump)

      288    0.000    0.000    0.001    0.000 reduction.py:71(duplicate)

        1    0.000    0.000    0.000    0.000 secrets.py:34(token_bytes)

        1    0.000    0.000    0.000    0.000 secrets.py:48(token_hex)

        1    0.000    0.000    0.000    0.000 shared_memory.py:185(__del__)

      118    0.000    0.000    0.000    0.000 shared_memory.py:204(buf)

       48    0.000    0.000    0.000    0.000 shared_memory.py:209(name)

        1    0.000    0.000    0.000    0.000 shared_memory.py:223(close)

       37    0.000    0.000    0.000    0.000 shared_memory.py:278(<lambda>)

        1    0.000    0.000    0.000    0.000 shared_memory.py:280(<lambda>)

        3    0.000    0.000    0.000    0.000 shared_memory.py:284(_extract_recreation_code)

        1    0.000    0.000    0.000    0.000 shared_memory.py:298(__init__)

        1    0.000    0.000    0.000    0.000 shared_memory.py:301(<listcomp>)

        4    0.000    0.000    0.000    0.000 shared_memory.py:310(<genexpr>)

        1    0.000    0.000    0.000    0.000 shared_memory.py:319(<listcomp>)

        4    0.000    0.000    0.000    0.000 shared_memory.py:346(<genexpr>)

        4    0.000    0.000    0.000    0.000 shared_memory.py:352(<genexpr>)

       38    0.000    0.000    0.000    0.000 shared_memory.py:371(_get_packing_format)

       38    0.000    0.000    0.000    0.000 shared_memory.py:387(_get_back_transform)

        1    0.000    0.000    0.000    0.000 shared_memory.py:40(_make_filename)

       38    0.000    0.000    0.001    0.000 shared_memory.py:424(__getitem__)

       48    0.000    0.000    0.000    0.000 shared_memory.py:474(__reduce__)

        2    0.000    0.000    0.000    0.000 shared_memory.py:490(_format_size_metainfo)

        2    0.000    0.000    0.000    0.000 shared_memory.py:495(_format_packing_metainfo)

        2    0.000    0.000    0.000    0.000 shared_memory.py:500(_format_back_transform_codes)

      117    0.000    0.000    0.000    0.000 shared_memory.py:505(_offset_data_start)

       78    0.000    0.000    0.000    0.000 shared_memory.py:511(_offset_packing_formats)

       39    0.000    0.000    0.000    0.000 shared_memory.py:515(_offset_back_transform_codes)

        1    0.000    0.000    0.000    0.000 shared_memory.py:75(__init__)

       48    0.000    0.000    0.000    0.000 spawn.py:138(_check_not_importing_main)

       48    0.001    0.000    0.002    0.000 spawn.py:160(get_preparation_data)

       96    0.000    0.000    0.000    0.000 spawn.py:45(get_executable)

       48    0.000    0.000    0.002    0.000 spawn.py:83(get_command_line)

      144    0.000    0.000    0.000    0.000 spawn.py:92(<genexpr>)

       48    0.000    0.000    0.000    0.000 subprocess.py:290(_optim_args_from_interpreter_flags)

       48    0.001    0.000    0.001    0.000 subprocess.py:300(_args_from_interpreter_flags)

      288    0.001    0.000    0.002    0.000 synchronize.py:100(__getstate__)

        6    0.000    0.000    0.000    0.000 synchronize.py:121(_make_name)

        4    0.000    0.000    0.000    0.000 synchronize.py:132(__init__)

        2    0.000    0.000    0.000    0.000 synchronize.py:168(__init__)

        1    0.000    0.000    0.000    0.000 synchronize.py:219(__init__)

       48    0.000    0.000    0.000    0.000 synchronize.py:226(__getstate__)

        6    0.000    0.000    0.234    0.039 synchronize.py:236(__enter__)

        6    0.000    0.000    0.000    0.000 synchronize.py:239(__exit__)

        1    0.000    0.000    0.000    0.000 synchronize.py:242(_make_methods)

        3    0.000    0.000    0.000    0.000 synchronize.py:277(notify)

        3    0.000    0.000    0.000    0.000 synchronize.py:303(notify_all)

        1    0.000    0.000    0.000    0.000 synchronize.py:330(__init__)

        3    0.000    0.000    0.235    0.078 synchronize.py:341(set)

        3    0.000    0.000    0.000    0.000 synchronize.py:347(clear)

        6    0.000    0.000    0.000    0.000 synchronize.py:50(__init__)

        6    0.000    0.000    0.000    0.000 synchronize.py:90(_make_methods)

        6    0.000    0.000    0.234    0.039 synchronize.py:94(__enter__)

        6    0.000    0.000    0.000    0.000 synchronize.py:97(__exit__)

        7    0.000    0.000    0.000    0.000 tempfile.py:143(rng)

        7    0.000    0.000    0.000    0.000 tempfile.py:154(__next__)

        1    0.000    0.000    0.000    0.000 tempfile.py:230(_get_candidate_names)

        1    0.000    0.000    0.000    0.000 tempfile.py:401(mktemp)

        1    0.000    0.000    0.000    0.000 tempfile.py:77(_exists)

       48    0.001    0.000    0.001    0.000 util.py:189(__init__)

       48    0.000    0.000    0.002    0.000 util.py:208(__call__)

       48    0.000    0.000    0.000    0.000 util.py:44(sub_debug)

        6    0.000    0.000    0.000    0.000 util.py:48(debug)

        1    0.000    0.000    0.000    0.000 {built-in method _struct.calcsize}

        4    0.000    0.000    0.000    0.000 {built-in method _struct.pack_into}

      114    0.000    0.000    0.000    0.000 {built-in method _struct.unpack_from}

      195    0.002    0.000    0.002    0.000 {built-in method _winapi.CloseHandle}

        1    0.000    0.000    0.000    0.000 {built-in method _winapi.ConnectNamedPipe}

        1    0.000    0.000    0.000    0.000 {built-in method _winapi.CreateFileMapping}

        1    0.000    0.000    0.000    0.000 {built-in method _winapi.CreateFile}

        1    0.000    0.000    0.000    0.000 {built-in method _winapi.CreateNamedPipe}

       48    0.001    0.000    0.001    0.000 {built-in method _winapi.CreatePipe}

       48    0.176    0.004    0.176    0.004 {built-in method _winapi.CreateProcess}

      336    0.001    0.000    0.001    0.000 {built-in method _winapi.DuplicateHandle}

      336    0.000    0.000    0.000    0.000 {built-in method _winapi.GetCurrentProcess}

       48    0.000    0.000    0.000    0.000 {built-in method _winapi.GetExitCodeProcess}

        1    0.000    0.000    0.000    0.000 {built-in method _winapi.GetLastError}

       48    0.000    0.000    0.000    0.000 {built-in method _winapi.OpenProcess}

       33    0.000    0.000    0.000    0.000 {built-in method _winapi.ReadFile}

        1    0.000    0.000    0.000    0.000 {built-in method _winapi.SetNamedPipeHandleState}

       20   17.480    0.874   17.480    0.874 {built-in method _winapi.WaitForMultipleObjects}

      408    0.628    0.002    0.628    0.002 {built-in method _winapi.WaitForSingleObject}

        1    0.000    0.000    0.000    0.000 {built-in method binascii.hexlify}

        1    0.000    0.000   20.362   20.362 {built-in method builtins.exec}

     1543    0.001    0.000    0.001    0.000 {built-in method builtins.getattr}

      108    0.000    0.000    0.000    0.000 {built-in method builtins.isinstance}

       54    0.000    0.000    0.000    0.000 {built-in method builtins.len}

      360    0.000    0.000    0.000    0.000 {built-in method builtins.max}

      104    0.000    0.000    0.000    0.000 {built-in method builtins.next}

        1    0.000    0.000    0.000    0.000 {built-in method builtins.sum}

       48    0.001    0.000    0.001    0.000 {built-in method io.open}

        3    0.000    0.000    0.000    0.000 {built-in method math.ceil}

       56    0.000    0.000    0.000    0.000 {built-in method math.floor}

       48    0.000    0.000    0.000    0.000 {built-in method msvcrt.open_osfhandle}

       48    0.000    0.000    0.000    0.000 {built-in method nt._path_normpath}

        3    0.000    0.000    0.000    0.000 {built-in method nt.cpu_count}

       99    0.000    0.000    0.000    0.000 {built-in method nt.fspath}

       48    0.000    0.000    0.000    0.000 {built-in method nt.getcwd}

      344    0.000    0.000    0.000    0.000 {built-in method nt.getpid}

        1    0.000    0.000    0.000    0.000 {built-in method nt.lstat}

        1    0.000    0.000    0.000    0.000 {built-in method nt.urandom}

        2    0.000    0.000    0.000    0.000 {built-in method time.time_ns}

       34    0.000    0.000    0.000    0.000 {method 'GetOverlappedResult' of '_winapi.Overlapped' objects}

        6    0.234    0.039    0.234    0.039 {method '__enter__' of '_multiprocessing.SemLock' objects}

       48    1.809    0.038    1.809    0.038 {method '__exit__' of '_io._IOBase' objects}

        6    0.000    0.000    0.000    0.000 {method '__exit__' of '_multiprocessing.SemLock' objects}

        3    0.000    0.000    0.000    0.000 {method '_is_mine' of '_multiprocessing.SemLock' objects}

       81    0.000    0.000    0.000    0.000 {method 'acquire' of '_multiprocessing.SemLock' objects}

       96    0.000    0.000    0.000    0.000 {method 'add' of 'set' objects}

       51    0.000    0.000    0.000    0.000 {method 'append' of 'list' objects}

        1    0.000    0.000    0.000    0.000 {method 'close' of 'mmap.mmap' objects}

      144    0.000    0.000    0.000    0.000 {method 'copy' of 'dict' objects}

       48    0.000    0.000    0.000    0.000 {method 'copy' of 'list' objects}

       40    0.000    0.000    0.000    0.000 {method 'decode' of 'bytes' objects}

        1    0.000    0.000    0.000    0.000 {method 'digest' of '_hashlib.HASH' objects}

        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

       96    0.000    0.000    0.000    0.000 {method 'discard' of 'set' objects}

       96    0.006    0.000    0.012    0.000 {method 'dump' of '_pickle.Pickler' objects}

        4    0.000    0.000    0.000    0.000 {method 'encode' of 'str' objects}

        2    0.000    0.000    0.000    0.000 {method 'find' of 'str' objects}

       48    0.000    0.000    0.000    0.000 {method 'get' of 'dict' objects}

       33    0.000    0.000    0.000    0.000 {method 'getbuffer' of '_winapi.Overlapped' objects}

       33    0.000    0.000    0.000    0.000 {method 'getvalue' of '_io.BytesIO' objects}

       48    0.000    0.000    0.000    0.000 {method 'index' of 'list' objects}

       96    0.000    0.000    0.000    0.000 {method 'items' of 'dict' objects}

      153    0.000    0.000    0.001    0.000 {method 'join' of 'str' objects}

       56    0.000    0.000    0.000    0.000 {method 'random' of '_random.Random' objects}

       35    0.000    0.000    0.000    0.000 {method 'release' of '_multiprocessing.SemLock' objects}

        1    0.000    0.000    0.000    0.000 {method 'release' of 'memoryview' objects}

       49    0.000    0.000    0.000    0.000 {method 'replace' of 'str' objects}

      153    0.000    0.000    0.000    0.000 {method 'rpartition' of 'str' objects}

       39    0.000    0.000    0.000    0.000 {method 'rstrip' of 'bytes' objects}

       96    0.000    0.000    0.000    0.000 {method 'startswith' of 'str' objects}

      144    0.000    0.000    0.000    0.000 {method 'update' of 'dict' objects}

        1    0.000    0.000    0.000    0.000 {method 'upper' of 'str' objects}

       33    0.000    0.000    0.000    0.000 {method 'write' of '_io.BytesIO' objects}



86464053 20.2589443 amongamongamong

Sha512 Hash: 0c0861dc3779cc1e7cc7b1edcdd1864617f3f4c67656724e47c94033ced9f1c0750807a20a7283df8cc52c27d3814fd5200d9ab27d308aaa7df550a70f155249

         13118 function calls in 22.426 seconds


   Ordered by: standard name


   ncalls  tottime  percall  cumtime  percall filename:lineno(function)

      153    0.000    0.000    0.000    0.000 <frozen importlib._bootstrap>:405(parent)

        1    0.000    0.000    0.000    0.000 <frozen ntpath>:107(join)

        2    0.000    0.000    0.000    0.000 <frozen ntpath>:154(splitdrive)

       48    0.000    0.000    0.000    0.000 <frozen ntpath>:538(normpath)

       48    0.000    0.000    0.000    0.000 <frozen ntpath>:87(isabs)

        1    0.000    0.000   22.426   22.426 <string>:1(<module>)

        1    0.001    0.001   22.424   22.424 MultiProcessorPipe.py:51(multiProcessor2)

       48    0.000    0.000    0.000    0.000 _weakrefset.py:39(_remove)

       48    0.000    0.000    0.000    0.000 _weakrefset.py:85(add)

        2    0.000    0.000    0.000    0.000 connection.py:118(__init__)

        2    0.000    0.000    0.000    0.000 connection.py:131(__del__)

       81    0.000    0.000    0.000    0.000 connection.py:135(_check_closed)

       33    0.000    0.000    0.000    0.000 connection.py:139(_check_readable)

       96    0.000    0.000    0.000    0.000 connection.py:159(readable)

       96    0.000    0.000    0.000    0.000 connection.py:164(writable)

       48    0.000    0.000    0.000    0.000 connection.py:169(fileno)

        2    0.000    0.000    0.000    0.000 connection.py:174(close)

       33    0.000    0.000   19.322    0.586 connection.py:208(recv_bytes)

        2    0.000    0.000    0.000    0.000 connection.py:277(_close)

       33    0.001    0.000   19.322    0.586 connection.py:310(_recv_bytes)

        1    0.000    0.000    0.000    0.000 connection.py:552(Pipe)

        1    0.000    0.000    0.000    0.000 connection.py:70(arbitrary_address)

       48    0.001    0.000    0.001    0.000 connection.py:973(reduce_pipe_connection)

        6    0.000    0.000    0.000    0.000 context.py:187(get_context)

        6    0.000    0.000    0.000    0.000 context.py:197(get_start_method)

       48    0.000    0.000    2.174    0.045 context.py:222(_Popen)

       50    0.000    0.000    0.000    0.000 context.py:237(get_context)

       48    0.000    0.000    0.000    0.000 context.py:253(get_start_method)

       48    0.001    0.000    2.174    0.045 context.py:333(_Popen)

     1008    0.000    0.000    0.001    0.000 context.py:365(get_spawning_popen)

       96    0.000    0.000    0.000    0.000 context.py:368(set_spawning_popen)

      336    0.000    0.000    0.000    0.000 context.py:371(assert_spawning)

        3    0.000    0.000    0.000    0.000 context.py:41(cpu_count)

        1    0.000    0.000    0.000    0.000 context.py:60(Pipe)

        2    0.000    0.000    0.000    0.000 context.py:65(Lock)

        1    0.000    0.000    0.000    0.000 context.py:75(Condition)

        4    0.000    0.000    0.000    0.000 context.py:80(Semaphore)

        1    0.000    0.000    0.000    0.000 context.py:90(Event)

      408    0.001    0.000    0.668    0.002 popen_spawn_win32.py:103(wait)

      360    0.000    0.000    0.001    0.000 popen_spawn_win32.py:121(poll)

       48    0.000    0.000    0.002    0.000 popen_spawn_win32.py:29(_close_handles)

       48    0.002    0.000    2.173    0.045 popen_spawn_win32.py:45(__init__)

      240    0.000    0.000    0.000    0.000 popen_spawn_win32.py:70(<genexpr>)

      288    0.000    0.000    0.001    0.000 popen_spawn_win32.py:99(duplicate_for_child)

       48    0.001    0.000    2.177    0.045 process.py:110(start)

       48    0.000    0.000    0.667    0.014 process.py:142(join)

       48    0.000    0.000    0.000    0.000 process.py:189(name)

       48    0.000    0.000    0.000    0.000 process.py:213(authkey)

       96    0.001    0.000    0.001    0.000 process.py:350(__reduce__)

      102    0.000    0.000    0.000    0.000 process.py:37(current_process)

       48    0.001    0.000    0.002    0.000 process.py:61(_cleanup)

       48    0.001    0.000    0.002    0.000 process.py:80(__init__)

       96    0.000    0.000    0.000    0.000 process.py:94(<genexpr>)

       96    0.000    0.000    0.000    0.000 process.py:99(_check_closed)

        7    0.000    0.000    0.000    0.000 random.py:480(choices)

        7    0.000    0.000    0.000    0.000 random.py:493(<listcomp>)

        1    0.000    0.000    0.000    0.000 random.py:808(randbytes)

       48    0.000    0.000    0.001    0.000 reduction.py:106(__init__)

       48    0.000    0.000    0.000    0.000 reduction.py:223(_reduce_partial)

       96    0.001    0.000    0.001    0.000 reduction.py:38(__init__)

       96    0.001    0.000    0.015    0.000 reduction.py:58(dump)

      288    0.000    0.000    0.001    0.000 reduction.py:71(duplicate)

        1    0.000    0.000    0.000    0.000 secrets.py:34(token_bytes)

        1    0.000    0.000    0.000    0.000 secrets.py:48(token_hex)

        1    0.000    0.000    0.000    0.000 shared_memory.py:185(__del__)

      118    0.000    0.000    0.000    0.000 shared_memory.py:204(buf)

       48    0.000    0.000    0.000    0.000 shared_memory.py:209(name)

        1    0.000    0.000    0.000    0.000 shared_memory.py:223(close)

       37    0.000    0.000    0.000    0.000 shared_memory.py:278(<lambda>)

        1    0.000    0.000    0.000    0.000 shared_memory.py:280(<lambda>)

        3    0.000    0.000    0.000    0.000 shared_memory.py:284(_extract_recreation_code)

        1    0.000    0.000    0.000    0.000 shared_memory.py:298(__init__)

        1    0.000    0.000    0.000    0.000 shared_memory.py:301(<listcomp>)

        4    0.000    0.000    0.000    0.000 shared_memory.py:310(<genexpr>)

        1    0.000    0.000    0.000    0.000 shared_memory.py:319(<listcomp>)

        4    0.000    0.000    0.000    0.000 shared_memory.py:346(<genexpr>)

        4    0.000    0.000    0.000    0.000 shared_memory.py:352(<genexpr>)

       38    0.000    0.000    0.000    0.000 shared_memory.py:371(_get_packing_format)

       38    0.000    0.000    0.000    0.000 shared_memory.py:387(_get_back_transform)

        1    0.000    0.000    0.000    0.000 shared_memory.py:40(_make_filename)

       38    0.000    0.000    0.001    0.000 shared_memory.py:424(__getitem__)

       48    0.000    0.000    0.000    0.000 shared_memory.py:474(__reduce__)

        2    0.000    0.000    0.000    0.000 shared_memory.py:490(_format_size_metainfo)

        2    0.000    0.000    0.000    0.000 shared_memory.py:495(_format_packing_metainfo)

        2    0.000    0.000    0.000    0.000 shared_memory.py:500(_format_back_transform_codes)

      117    0.000    0.000    0.000    0.000 shared_memory.py:505(_offset_data_start)

       78    0.000    0.000    0.000    0.000 shared_memory.py:511(_offset_packing_formats)

       39    0.000    0.000    0.000    0.000 shared_memory.py:515(_offset_back_transform_codes)

        1    0.000    0.000    0.000    0.000 shared_memory.py:75(__init__)

       48    0.000    0.000    0.000    0.000 spawn.py:138(_check_not_importing_main)

       48    0.001    0.000    0.002    0.000 spawn.py:160(get_preparation_data)

       96    0.000    0.000    0.000    0.000 spawn.py:45(get_executable)

       48    0.001    0.000    0.002    0.000 spawn.py:83(get_command_line)

      144    0.000    0.000    0.000    0.000 spawn.py:92(<genexpr>)

       48    0.000    0.000    0.000    0.000 subprocess.py:290(_optim_args_from_interpreter_flags)

       48    0.001    0.000    0.001    0.000 subprocess.py:300(_args_from_interpreter_flags)

      288    0.001    0.000    0.003    0.000 synchronize.py:100(__getstate__)

        6    0.000    0.000    0.000    0.000 synchronize.py:121(_make_name)

        4    0.000    0.000    0.000    0.000 synchronize.py:132(__init__)

        2    0.000    0.000    0.000    0.000 synchronize.py:168(__init__)

        1    0.000    0.000    0.000    0.000 synchronize.py:219(__init__)

       48    0.000    0.000    0.000    0.000 synchronize.py:226(__getstate__)

        6    0.000    0.000    0.251    0.042 synchronize.py:236(__enter__)

        6    0.000    0.000    0.000    0.000 synchronize.py:239(__exit__)

        1    0.000    0.000    0.000    0.000 synchronize.py:242(_make_methods)

        3    0.000    0.000    0.000    0.000 synchronize.py:277(notify)

        3    0.000    0.000    0.000    0.000 synchronize.py:303(notify_all)

        1    0.000    0.000    0.000    0.000 synchronize.py:330(__init__)

        3    0.000    0.000    0.252    0.084 synchronize.py:341(set)

        3    0.000    0.000    0.000    0.000 synchronize.py:347(clear)

        6    0.000    0.000    0.000    0.000 synchronize.py:50(__init__)

        6    0.000    0.000    0.000    0.000 synchronize.py:90(_make_methods)

        6    0.000    0.000    0.251    0.042 synchronize.py:94(__enter__)

        6    0.000    0.000    0.000    0.000 synchronize.py:97(__exit__)

        7    0.000    0.000    0.000    0.000 tempfile.py:143(rng)

        7    0.000    0.000    0.000    0.000 tempfile.py:154(__next__)

        1    0.000    0.000    0.000    0.000 tempfile.py:230(_get_candidate_names)

        1    0.000    0.000    0.000    0.000 tempfile.py:401(mktemp)

        1    0.000    0.000    0.000    0.000 tempfile.py:77(_exists)

       48    0.001    0.000    0.001    0.000 util.py:189(__init__)

       48    0.000    0.000    0.002    0.000 util.py:208(__call__)

       48    0.000    0.000    0.000    0.000 util.py:44(sub_debug)

        6    0.000    0.000    0.000    0.000 util.py:48(debug)

        1    0.000    0.000    0.000    0.000 {built-in method _struct.calcsize}

        4    0.000    0.000    0.000    0.000 {built-in method _struct.pack_into}

      114    0.000    0.000    0.000    0.000 {built-in method _struct.unpack_from}

      195    0.002    0.000    0.002    0.000 {built-in method _winapi.CloseHandle}

        1    0.000    0.000    0.000    0.000 {built-in method _winapi.ConnectNamedPipe}

        1    0.000    0.000    0.000    0.000 {built-in method _winapi.CreateFileMapping}

        1    0.000    0.000    0.000    0.000 {built-in method _winapi.CreateFile}

        1    0.000    0.000    0.000    0.000 {built-in method _winapi.CreateNamedPipe}

       48    0.001    0.000    0.001    0.000 {built-in method _winapi.CreatePipe}

       48    0.162    0.003    0.162    0.003 {built-in method _winapi.CreateProcess}

      336    0.001    0.000    0.001    0.000 {built-in method _winapi.DuplicateHandle}

      336    0.000    0.000    0.000    0.000 {built-in method _winapi.GetCurrentProcess}

       48    0.000    0.000    0.000    0.000 {built-in method _winapi.GetExitCodeProcess}

        1    0.000    0.000    0.000    0.000 {built-in method _winapi.GetLastError}

       48    0.000    0.000    0.000    0.000 {built-in method _winapi.OpenProcess}

       33    0.000    0.000    0.000    0.000 {built-in method _winapi.ReadFile}

        1    0.000    0.000    0.000    0.000 {built-in method _winapi.SetNamedPipeHandleState}

       21   19.321    0.920   19.321    0.920 {built-in method _winapi.WaitForMultipleObjects}

      408    0.667    0.002    0.667    0.002 {built-in method _winapi.WaitForSingleObject}

        1    0.000    0.000    0.000    0.000 {built-in method binascii.hexlify}

        1    0.000    0.000   22.426   22.426 {built-in method builtins.exec}

     1543    0.001    0.000    0.001    0.000 {built-in method builtins.getattr}

      108    0.000    0.000    0.000    0.000 {built-in method builtins.isinstance}

       54    0.000    0.000    0.000    0.000 {built-in method builtins.len}

      360    0.000    0.000    0.000    0.000 {built-in method builtins.max}

      104    0.000    0.000    0.000    0.000 {built-in method builtins.next}

        1    0.000    0.000    0.000    0.000 {built-in method builtins.sum}

       48    0.001    0.000    0.001    0.000 {built-in method io.open}

        3    0.000    0.000    0.000    0.000 {built-in method math.ceil}

       56    0.000    0.000    0.000    0.000 {built-in method math.floor}

       48    0.000    0.000    0.000    0.000 {built-in method msvcrt.open_osfhandle}

       48    0.000    0.000    0.000    0.000 {built-in method nt._path_normpath}

        3    0.000    0.000    0.000    0.000 {built-in method nt.cpu_count}

       99    0.000    0.000    0.000    0.000 {built-in method nt.fspath}

       48    0.000    0.000    0.000    0.000 {built-in method nt.getcwd}

      344    0.000    0.000    0.000    0.000 {built-in method nt.getpid}

        1    0.000    0.000    0.000    0.000 {built-in method nt.lstat}

        1    0.000    0.000    0.000    0.000 {built-in method nt.urandom}

        2    0.000    0.000    0.000    0.000 {built-in method time.time_ns}

       34    0.000    0.000    0.000    0.000 {method 'GetOverlappedResult' of '_winapi.Overlapped' objects}

        6    0.251    0.042    0.251    0.042 {method '__enter__' of '_multiprocessing.SemLock' objects}

       48    1.985    0.041    1.985    0.041 {method '__exit__' of '_io._IOBase' objects}

        6    0.000    0.000    0.000    0.000 {method '__exit__' of '_multiprocessing.SemLock' objects}

        3    0.000    0.000    0.000    0.000 {method '_is_mine' of '_multiprocessing.SemLock' objects}

       81    0.000    0.000    0.000    0.000 {method 'acquire' of '_multiprocessing.SemLock' objects}

       96    0.000    0.000    0.000    0.000 {method 'add' of 'set' objects}

       51    0.000    0.000    0.000    0.000 {method 'append' of 'list' objects}

        1    0.000    0.000    0.000    0.000 {method 'close' of 'mmap.mmap' objects}

      144    0.000    0.000    0.000    0.000 {method 'copy' of 'dict' objects}

       48    0.000    0.000    0.000    0.000 {method 'copy' of 'list' objects}

       40    0.000    0.000    0.000    0.000 {method 'decode' of 'bytes' objects}

        1    0.000    0.000    0.000    0.000 {method 'digest' of '_hashlib.HASH' objects}

        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

       96    0.000    0.000    0.000    0.000 {method 'discard' of 'set' objects}

       96    0.007    0.000    0.013    0.000 {method 'dump' of '_pickle.Pickler' objects}

        4    0.000    0.000    0.000    0.000 {method 'encode' of 'str' objects}

        2    0.000    0.000    0.000    0.000 {method 'find' of 'str' objects}

       48    0.000    0.000    0.000    0.000 {method 'get' of 'dict' objects}

       33    0.000    0.000    0.000    0.000 {method 'getbuffer' of '_winapi.Overlapped' objects}

       33    0.000    0.000    0.000    0.000 {method 'getvalue' of '_io.BytesIO' objects}

       48    0.000    0.000    0.000    0.000 {method 'index' of 'list' objects}

       96    0.000    0.000    0.000    0.000 {method 'items' of 'dict' objects}

      153    0.000    0.000    0.001    0.000 {method 'join' of 'str' objects}

       56    0.000    0.000    0.000    0.000 {method 'random' of '_random.Random' objects}

       35    0.000    0.000    0.000    0.000 {method 'release' of '_multiprocessing.SemLock' objects}

        1    0.000    0.000    0.000    0.000 {method 'release' of 'memoryview' objects}

       49    0.000    0.000    0.000    0.000 {method 'replace' of 'str' objects}

      153    0.000    0.000    0.000    0.000 {method 'rpartition' of 'str' objects}

       39    0.000    0.000    0.000    0.000 {method 'rstrip' of 'bytes' objects}

       96    0.000    0.000    0.000    0.000 {method 'startswith' of 'str' objects}

      144    0.000    0.000    0.000    0.000 {method 'update' of 'dict' objects}

        1    0.000    0.000    0.000    0.000 {method 'upper' of 'str' objects}

       33    0.000    0.000    0.000    0.000 {method 'write' of '_io.BytesIO' objects}



88033400 24.2802704 amongamongamong

Enter Password: q

Done

Several Processors with Pipes Version 2

The first step in optimizing the processor code was to run a cProfile on the code, that then highlighted many bottlenecks that I could solve. The main bottlenecks unsurprisingly involved hashing, in that new, update and digest where the main times but also encoding and join. For the hashing bottleneck I brought new out of the inner loop and instead used update and copy to update a hash object instead of creating a new one. For the encoding I opted to encode words in main as that let me encode all permutations before hand. For join there was nothing specific but it did decrease most likely due to using bytes instead of strings. In terms of performance  there was a drastic decrease with it taking ~14 seconds for the hardest password in the 500 word dictionary of amongamongamong. Without some major changes I doubt the processing code will be any faster.

Before cProfile

Longest Password is amongamongamong and will take around 86188000 iterations and around 21.55 seconds

Enter Password: amongamongamong

Sha256 Hash: 922f052e4cc8f014de935fb51ed139c1e21d091accf6c9d1f89f2c41310e0969

85592459 20.6133822 amongamongamong

         48000204 function calls in 20.794 seconds


   Ordered by: standard name


   ncalls  tottime  percall  cumtime  percall filename:lineno(function)

        1    0.000    0.000    0.000    0.000 <frozen importlib._bootstrap>:405(parent)

        1    0.000    0.000   20.794   20.794 <string>:1(<module>)

        1    0.000    0.000    0.000    0.000 MultiProcessorPipe2.py:17(__init__)

        1   10.553   10.553   20.793   20.793 MultiProcessorPipe2.py:51(run)

        1    0.000    0.000    0.000    0.000 _weakrefset.py:85(add)

        1    0.000    0.000    0.000    0.000 connection.py:135(_check_closed)

        1    0.000    0.000    0.000    0.000 connection.py:143(_check_writable)

        1    0.000    0.000    0.000    0.000 connection.py:182(send_bytes)

        1    0.000    0.000    0.000    0.000 connection.py:284(_send_bytes)

        1    0.000    0.000    0.000    0.000 context.py:197(get_start_method)

        1    0.000    0.000    0.000    0.000 context.py:237(get_context)

        1    0.000    0.000    0.000    0.000 context.py:65(Lock)

  8000000    2.343    0.000    4.931    0.000 hashlib.py:152(__hash_new)

        1    0.000    0.000    0.000    0.000 process.py:37(current_process)

        1    0.000    0.000    0.000    0.000 random.py:480(choices)

        1    0.000    0.000    0.000    0.000 random.py:493(<listcomp>)

        1    0.000    0.000    0.000    0.000 random.py:808(randbytes)

        1    0.000    0.000    0.000    0.000 secrets.py:34(token_bytes)

        1    0.000    0.000    0.000    0.000 secrets.py:48(token_hex)

        1    0.000    0.000    0.000    0.000 shared_memory.py:185(__del__)

       11    0.000    0.000    0.000    0.000 shared_memory.py:204(buf)

        1    0.000    0.000    0.000    0.000 shared_memory.py:223(close)

        1    0.000    0.000    0.000    0.000 shared_memory.py:278(<lambda>)

        4    0.000    0.000    0.000    0.000 shared_memory.py:284(_extract_recreation_code)

        1    0.000    0.000    0.000    0.000 shared_memory.py:298(__init__)

        1    0.000    0.000    0.000    0.000 shared_memory.py:301(<listcomp>)

        4    0.000    0.000    0.000    0.000 shared_memory.py:310(<genexpr>)

        1    0.000    0.000    0.000    0.000 shared_memory.py:319(<listcomp>)

        4    0.000    0.000    0.000    0.000 shared_memory.py:346(<genexpr>)

        4    0.000    0.000    0.000    0.000 shared_memory.py:352(<genexpr>)

        2    0.000    0.000    0.000    0.000 shared_memory.py:371(_get_packing_format)

        1    0.000    0.000    0.000    0.000 shared_memory.py:387(_get_back_transform)

        1    0.000    0.000    0.000    0.000 shared_memory.py:40(_make_filename)

        1    0.000    0.000    0.000    0.000 shared_memory.py:402(_set_packing_format_and_transform)

        1    0.000    0.000    0.000    0.000 shared_memory.py:424(__getitem__)

        1    0.000    0.000    0.000    0.000 shared_memory.py:441(__setitem__)

        2    0.000    0.000    0.000    0.000 shared_memory.py:490(_format_size_metainfo)

        2    0.000    0.000    0.000    0.000 shared_memory.py:495(_format_packing_metainfo)

        2    0.000    0.000    0.000    0.000 shared_memory.py:500(_format_back_transform_codes)

       10    0.000    0.000    0.000    0.000 shared_memory.py:505(_offset_data_start)

        7    0.000    0.000    0.000    0.000 shared_memory.py:511(_offset_packing_formats)

        3    0.000    0.000    0.000    0.000 shared_memory.py:515(_offset_back_transform_codes)

        1    0.000    0.000    0.000    0.000 shared_memory.py:75(__init__)

        1    0.000    0.000    0.000    0.000 synchronize.py:121(_make_name)

        1    0.000    0.000    0.000    0.000 synchronize.py:168(__init__)

        1    0.000    0.000    0.000    0.000 synchronize.py:50(__init__)

        1    0.000    0.000    0.000    0.000 synchronize.py:90(_make_methods)

        1    0.000    0.000    0.000    0.000 synchronize.py:94(__enter__)

        1    0.000    0.000    0.000    0.000 synchronize.py:97(__exit__)

        1    0.000    0.000    0.000    0.000 tempfile.py:143(rng)

        1    0.000    0.000    0.000    0.000 tempfile.py:154(__next__)

        1    0.000    0.000    0.000    0.000 threading.py:1206(daemon)

        1    0.000    0.000    0.000    0.000 threading.py:1324(_make_invoke_excepthook)

        1    0.000    0.000    0.000    0.000 threading.py:1453(current_thread)

        1    0.000    0.000    0.000    0.000 threading.py:243(__init__)

        1    0.000    0.000    0.000    0.000 threading.py:271(__enter__)

        1    0.000    0.000    0.000    0.000 threading.py:274(__exit__)

        1    0.000    0.000    0.000    0.000 threading.py:280(_release_save)

        1    0.000    0.000    0.000    0.000 threading.py:283(_acquire_restore)

        1    0.000    0.000    0.000    0.000 threading.py:286(_is_owned)

        1    0.000    0.000    0.001    0.001 threading.py:295(wait)

        1    0.000    0.000    0.000    0.000 threading.py:562(__init__)

        1    0.000    0.000    0.000    0.000 threading.py:575(is_set)

        1    0.000    0.000    0.001    0.001 threading.py:611(wait)

        1    0.000    0.000    0.000    0.000 threading.py:811(_newname)

        1    0.000    0.000    0.000    0.000 threading.py:856(__init__)

        1    0.000    0.000    0.001    0.001 threading.py:945(start)

        1    0.000    0.000    0.000    0.000 util.py:48(debug)

  8000000    2.588    0.000    2.588    0.000 {built-in method _hashlib.new}

        1    0.000    0.000    0.000    0.000 {built-in method _struct.calcsize}

        7    0.000    0.000    0.000    0.000 {built-in method _struct.pack_into}

        4    0.000    0.000    0.000    0.000 {built-in method _struct.unpack_from}

        2    0.000    0.000    0.000    0.000 {built-in method _thread.allocate_lock}

        1    0.000    0.000    0.000    0.000 {built-in method _thread.get_ident}

        1    0.000    0.000    0.000    0.000 {built-in method _thread.start_new_thread}

        1    0.000    0.000    0.000    0.000 {built-in method _winapi.CloseHandle}

        1    0.000    0.000    0.000    0.000 {built-in method _winapi.CreateFileMapping}

        1    0.000    0.000    0.000    0.000 {built-in method _winapi.GetLastError}

        1    0.000    0.000    0.000    0.000 {built-in method _winapi.WriteFile}

        1    0.000    0.000    0.000    0.000 {built-in method binascii.hexlify}

        1    0.000    0.000   20.794   20.794 {built-in method builtins.exec}

        1    0.000    0.000    0.000    0.000 {built-in method builtins.getattr}

       11    0.000    0.000    0.000    0.000 {built-in method builtins.isinstance}

        8    0.000    0.000    0.000    0.000 {built-in method builtins.len}

        1    0.000    0.000    0.000    0.000 {built-in method builtins.next}

        1    0.000    0.000    0.000    0.000 {built-in method builtins.sum}

        8    0.000    0.000    0.000    0.000 {built-in method math.floor}

        1    0.000    0.000    0.000    0.000 {built-in method nt.getpid}

        1    0.000    0.000    0.000    0.000 {built-in method nt.urandom}

        1    0.000    0.000    0.000    0.000 {method 'GetOverlappedResult' of '_winapi.Overlapped' objects}

        1    0.000    0.000    0.000    0.000 {method '__enter__' of '_multiprocessing.SemLock' objects}

        1    0.000    0.000    0.000    0.000 {method '__enter__' of '_thread.lock' objects}

        1    0.000    0.000    0.000    0.000 {method '__exit__' of '_multiprocessing.SemLock' objects}

        1    0.000    0.000    0.000    0.000 {method '__exit__' of '_thread.RLock' objects}

        1    0.000    0.000    0.000    0.000 {method '__exit__' of '_thread.lock' objects}

        4    0.001    0.000    0.001    0.000 {method 'acquire' of '_thread.lock' objects}

        1    0.000    0.000    0.000    0.000 {method 'add' of 'set' objects}

        1    0.000    0.000    0.000    0.000 {method 'append' of 'collections.deque' objects}

        3    0.000    0.000    0.000    0.000 {method 'append' of 'list' objects}

        1    0.000    0.000    0.000    0.000 {method 'close' of 'mmap.mmap' objects}

        3    0.000    0.000    0.000    0.000 {method 'decode' of 'bytes' objects}

  8000000    2.793    0.000    2.793    0.000 {method 'digest' of '_hashlib.HASH' objects}

        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

  8000004    0.766    0.000    0.766    0.000 {method 'encode' of 'str' objects}

  8000003    0.966    0.000    0.966    0.000 {method 'join' of 'str' objects}

        8    0.000    0.000    0.000    0.000 {method 'random' of '_random.Random' objects}

        1    0.000    0.000    0.000    0.000 {method 'release' of '_thread.lock' objects}

        1    0.000    0.000    0.000    0.000 {method 'release' of 'memoryview' objects}

        1    0.000    0.000    0.000    0.000 {method 'rpartition' of 'str' objects}

        2    0.000    0.000    0.000    0.000 {method 'rstrip' of 'bytes' objects}

  8000000    0.784    0.000    0.784    0.000 {method 'update' of '_hashlib.HASH' objects}



Sha512 Hash: 0c0861dc3779cc1e7cc7b1edcdd1864617f3f4c67656724e47c94033ced9f1c0750807a20a7283df8cc52c27d3814fd5200d9ab27d308aaa7df550a70f155249

84541560 23.5305474 amongamongamong

         48000204 function calls in 22.861 seconds


   Ordered by: standard name


   ncalls  tottime  percall  cumtime  percall filename:lineno(function)

        1    0.000    0.000    0.000    0.000 <frozen importlib._bootstrap>:405(parent)

        1    0.000    0.000   22.860   22.860 <string>:1(<module>)

        1    0.000    0.000    0.000    0.000 MultiProcessorPipe2.py:17(__init__)

        1   10.823   10.823   22.860   22.860 MultiProcessorPipe2.py:51(run)

        1    0.000    0.000    0.000    0.000 _weakrefset.py:85(add)

        1    0.000    0.000    0.000    0.000 connection.py:135(_check_closed)

        1    0.000    0.000    0.000    0.000 connection.py:143(_check_writable)

        1    0.000    0.000    0.000    0.000 connection.py:182(send_bytes)

        1    0.000    0.000    0.000    0.000 connection.py:284(_send_bytes)

        1    0.000    0.000    0.000    0.000 context.py:197(get_start_method)

        1    0.000    0.000    0.000    0.000 context.py:237(get_context)

        1    0.000    0.000    0.000    0.000 context.py:65(Lock)

  8000000    2.313    0.000    4.896    0.000 hashlib.py:152(__hash_new)

        1    0.000    0.000    0.000    0.000 process.py:37(current_process)

        1    0.000    0.000    0.000    0.000 random.py:480(choices)

        1    0.000    0.000    0.000    0.000 random.py:493(<listcomp>)

        1    0.000    0.000    0.000    0.000 random.py:808(randbytes)

        1    0.000    0.000    0.000    0.000 secrets.py:34(token_bytes)

        1    0.000    0.000    0.000    0.000 secrets.py:48(token_hex)

        1    0.000    0.000    0.000    0.000 shared_memory.py:185(__del__)

       11    0.000    0.000    0.000    0.000 shared_memory.py:204(buf)

        1    0.000    0.000    0.000    0.000 shared_memory.py:223(close)

        1    0.000    0.000    0.000    0.000 shared_memory.py:278(<lambda>)

        4    0.000    0.000    0.000    0.000 shared_memory.py:284(_extract_recreation_code)

        1    0.000    0.000    0.000    0.000 shared_memory.py:298(__init__)

        1    0.000    0.000    0.000    0.000 shared_memory.py:301(<listcomp>)

        4    0.000    0.000    0.000    0.000 shared_memory.py:310(<genexpr>)

        1    0.000    0.000    0.000    0.000 shared_memory.py:319(<listcomp>)

        4    0.000    0.000    0.000    0.000 shared_memory.py:346(<genexpr>)

        4    0.000    0.000    0.000    0.000 shared_memory.py:352(<genexpr>)

        2    0.000    0.000    0.000    0.000 shared_memory.py:371(_get_packing_format)

        1    0.000    0.000    0.000    0.000 shared_memory.py:387(_get_back_transform)

        1    0.000    0.000    0.000    0.000 shared_memory.py:40(_make_filename)

        1    0.000    0.000    0.000    0.000 shared_memory.py:402(_set_packing_format_and_transform)

        1    0.000    0.000    0.000    0.000 shared_memory.py:424(__getitem__)

        1    0.000    0.000    0.000    0.000 shared_memory.py:441(__setitem__)

        2    0.000    0.000    0.000    0.000 shared_memory.py:490(_format_size_metainfo)

        2    0.000    0.000    0.000    0.000 shared_memory.py:495(_format_packing_metainfo)

        2    0.000    0.000    0.000    0.000 shared_memory.py:500(_format_back_transform_codes)

       10    0.000    0.000    0.000    0.000 shared_memory.py:505(_offset_data_start)

        7    0.000    0.000    0.000    0.000 shared_memory.py:511(_offset_packing_formats)

        3    0.000    0.000    0.000    0.000 shared_memory.py:515(_offset_back_transform_codes)

        1    0.000    0.000    0.000    0.000 shared_memory.py:75(__init__)

        1    0.000    0.000    0.000    0.000 synchronize.py:121(_make_name)

        1    0.000    0.000    0.000    0.000 synchronize.py:168(__init__)

        1    0.000    0.000    0.000    0.000 synchronize.py:50(__init__)

        1    0.000    0.000    0.000    0.000 synchronize.py:90(_make_methods)

        1    0.000    0.000    0.000    0.000 synchronize.py:94(__enter__)

        1    0.000    0.000    0.000    0.000 synchronize.py:97(__exit__)

        1    0.000    0.000    0.000    0.000 tempfile.py:143(rng)

        1    0.000    0.000    0.000    0.000 tempfile.py:154(__next__)

        1    0.000    0.000    0.000    0.000 threading.py:1206(daemon)

        1    0.000    0.000    0.000    0.000 threading.py:1324(_make_invoke_excepthook)

        1    0.000    0.000    0.000    0.000 threading.py:1453(current_thread)

        1    0.000    0.000    0.000    0.000 threading.py:243(__init__)

        1    0.000    0.000    0.000    0.000 threading.py:271(__enter__)

        1    0.000    0.000    0.000    0.000 threading.py:274(__exit__)

        1    0.000    0.000    0.000    0.000 threading.py:280(_release_save)

        1    0.000    0.000    0.000    0.000 threading.py:283(_acquire_restore)

        1    0.000    0.000    0.000    0.000 threading.py:286(_is_owned)

        1    0.000    0.000    0.001    0.001 threading.py:295(wait)

        1    0.000    0.000    0.000    0.000 threading.py:562(__init__)

        1    0.000    0.000    0.000    0.000 threading.py:575(is_set)

        1    0.000    0.000    0.001    0.001 threading.py:611(wait)

        1    0.000    0.000    0.000    0.000 threading.py:811(_newname)

        1    0.000    0.000    0.000    0.000 threading.py:856(__init__)

        1    0.000    0.000    0.001    0.001 threading.py:945(start)

        1    0.000    0.000    0.000    0.000 util.py:48(debug)

  8000000    2.583    0.000    2.583    0.000 {built-in method _hashlib.new}

        1    0.000    0.000    0.000    0.000 {built-in method _struct.calcsize}

        7    0.000    0.000    0.000    0.000 {built-in method _struct.pack_into}

        4    0.000    0.000    0.000    0.000 {built-in method _struct.unpack_from}

        2    0.000    0.000    0.000    0.000 {built-in method _thread.allocate_lock}

        1    0.000    0.000    0.000    0.000 {built-in method _thread.get_ident}

        1    0.000    0.000    0.000    0.000 {built-in method _thread.start_new_thread}

        1    0.000    0.000    0.000    0.000 {built-in method _winapi.CloseHandle}

        1    0.000    0.000    0.000    0.000 {built-in method _winapi.CreateFileMapping}

        1    0.000    0.000    0.000    0.000 {built-in method _winapi.GetLastError}

        1    0.000    0.000    0.000    0.000 {built-in method _winapi.WriteFile}

        1    0.000    0.000    0.000    0.000 {built-in method binascii.hexlify}

        1    0.000    0.000   22.861   22.861 {built-in method builtins.exec}

        1    0.000    0.000    0.000    0.000 {built-in method builtins.getattr}

       11    0.000    0.000    0.000    0.000 {built-in method builtins.isinstance}

        8    0.000    0.000    0.000    0.000 {built-in method builtins.len}

        1    0.000    0.000    0.000    0.000 {built-in method builtins.next}

        1    0.000    0.000    0.000    0.000 {built-in method builtins.sum}

        8    0.000    0.000    0.000    0.000 {built-in method math.floor}

        1    0.000    0.000    0.000    0.000 {built-in method nt.getpid}

        1    0.000    0.000    0.000    0.000 {built-in method nt.urandom}

        1    0.000    0.000    0.000    0.000 {method 'GetOverlappedResult' of '_winapi.Overlapped' objects}

        1    0.000    0.000    0.000    0.000 {method '__enter__' of '_multiprocessing.SemLock' objects}

        1    0.000    0.000    0.000    0.000 {method '__enter__' of '_thread.lock' objects}

        1    0.000    0.000    0.000    0.000 {method '__exit__' of '_multiprocessing.SemLock' objects}

        1    0.000    0.000    0.000    0.000 {method '__exit__' of '_thread.RLock' objects}

        1    0.000    0.000    0.000    0.000 {method '__exit__' of '_thread.lock' objects}

        4    0.001    0.000    0.001    0.000 {method 'acquire' of '_thread.lock' objects}

        1    0.000    0.000    0.000    0.000 {method 'add' of 'set' objects}

        1    0.000    0.000    0.000    0.000 {method 'append' of 'collections.deque' objects}

        3    0.000    0.000    0.000    0.000 {method 'append' of 'list' objects}

        1    0.000    0.000    0.000    0.000 {method 'close' of 'mmap.mmap' objects}

        3    0.000    0.000    0.000    0.000 {method 'decode' of 'bytes' objects}

  8000000    4.579    0.000    4.579    0.000 {method 'digest' of '_hashlib.HASH' objects}

        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

  8000004    0.768    0.000    0.768    0.000 {method 'encode' of 'str' objects}

  8000003    0.997    0.000    0.997    0.000 {method 'join' of 'str' objects}

        8    0.000    0.000    0.000    0.000 {method 'random' of '_random.Random' objects}

        1    0.000    0.000    0.000    0.000 {method 'release' of '_thread.lock' objects}

        1    0.000    0.000    0.000    0.000 {method 'release' of 'memoryview' objects}

        1    0.000    0.000    0.000    0.000 {method 'rpartition' of 'str' objects}

        2    0.000    0.000    0.000    0.000 {method 'rstrip' of 'bytes' objects}

  8000000    0.796    0.000    0.796    0.000 {method 'update' of '_hashlib.HASH' objects}



Enter Password: q

Done

Several Processors with Pipes Version 2 Code

import itertools

import hashlib

import multiprocessing.shared_memory

import matplotlib as plt

import time

import multiprocessing 

import threading

import cProfile

import math

from multiprocessing import shared_memory


#Converges the geometric series for when starting at 1

def geometricSeries(a: int, r: int, n: int):

    return a * r * ((r ** n - 1) // (r - 1))


class CancellationToken:

   def __init__(self):

       self.is_cancelled = False


   def cancel(self):

       self.is_cancelled = True


def wait(event, token):

    event.wait()

    token.cancel()


def run(perms, arr, algorithm, password, words, lock, conn, event):

    count = 0

    token = CancellationToken()

    thread = threading.Thread(target=wait, args=[event, token])

    thread.start()

    for p in perms:

        word = b''.join(p)

        hash = hashlib.new(algorithm, word)

        for w in words:

            clone = hash.copy()

            clone.update(w)

            count += 1

            if clone.digest() == password:

                event.set()

                with lock:

                    arr[2] = word + w

                    arr[1] = True

            elif token.is_cancelled: break

        if token.is_cancelled: break

    with lock:

        arr[0] = arr[0] + count

        conn.send_bytes(b'\x00')

    #thread.join()



def multiProcessor2(wordLimit: int, words: list, password: bytes, algorithm: str):

    start = time.time_ns()

    arr = shared_memory.ShareableList([0, False, "\0" * 100])

    lock = multiprocessing.Lock()

    recv, send = multiprocessing.Pipe()

    event = multiprocessing.Event()

    for i in range(1, wordLimit + 1):

        perms = itertools.product(words, repeat=i - 1)

        wordsLen = len(words)

        size = math.ceil(wordsLen / multiprocessing.cpu_count())

        processes = []

        for j in range(0, wordsLen, size):

            p = multiprocessing.Process(target=run,args=[perms, arr, algorithm, password, words[j : j + size], lock, send, event])

            p.start()

            processes.append(p)

            if arr[1]: break


        completed = 0

        while completed != len(processes):

            recv.recv_bytes()

            if arr[1]:

                break

            completed += 1


        event.set()

        for p in processes:

            p.join()

        event.clear()

        if arr[1]:

            break

    recv.close()

    send.close()

    return arr[0], (time.time_ns() - start) / 1e9, arr[2].decode()

        


if __name__ == "__main__":

    wordLimit = 3

    dictonaryName = "MediumDictionary.txt"

    hashAlgorithms = ['sha256', 'sha512']

    f = open(dictonaryName, "r")

    words = f.read().splitlines()

    f.close()

    maxCount = geometricSeries(1,len(words),wordLimit - 1) + ((len(words) ** wordLimit) // multiprocessing.cpu_count()) * 11

    print(f"Longest Password is {words[-1] * wordLimit} and will take around {maxCount} iterations and around {round(maxCount * 2.5e-7,2)} seconds")


    password = input("Enter Password: ")

    words = [w.encode() for w in words]

    while password != "q":

        for h in hashAlgorithms:

            hash = hashlib.new(h)

            hash.update(password.encode()) #Hashes the password

            print(f"{h.capitalize()} Hash: {hash.hexdigest()}") #Prints nice Hex

            breakCount, breakTime, value = multiProcessor2(wordLimit, words, hash.digest(), h)

            #cProfile.run('multiProcessor2(wordLimit, words, hash.digest(), h)')

            print(breakCount, breakTime, value)

            recv, send = multiprocessing.Pipe() #amongamongbut

            event = multiprocessing.Event()

            cProfile.run('run(itertools.product(words, repeat=2), shared_memory.ShareableList([0, False, 0]), h, password, words[0 : 32], multiprocessing.Lock(), send, event)')

            event.set()

        password = input("Enter Password: ")

    print("Done") 

After cProfile

Longest Password is amongamongamong and will take around 86188000 iterations and around 21.55 seconds

Enter Password: amongamongamong

Sha256 Hash: 922f052e4cc8f014de935fb51ed139c1e21d091accf6c9d1f89f2c41310e0969

94068503 13.3223273 amongamongamong

         24750204 function calls in 10.606 seconds


   Ordered by: standard name


   ncalls  tottime  percall  cumtime  percall filename:lineno(function)

        1    0.000    0.000    0.000    0.000 <frozen importlib._bootstrap>:405(parent)

        1    0.000    0.000   10.606   10.606 <string>:1(<module>)

        1    0.000    0.000    0.000    0.000 MultiProcessorPipe2.py:17(__init__)

        1    5.392    5.392   10.606   10.606 MultiProcessorPipe2.py:27(run)

        1    0.000    0.000    0.000    0.000 _weakrefset.py:85(add)

        1    0.000    0.000    0.000    0.000 connection.py:135(_check_closed)

        1    0.000    0.000    0.000    0.000 connection.py:143(_check_writable)

        1    0.000    0.000    0.000    0.000 connection.py:182(send_bytes)

        1    0.000    0.000    0.000    0.000 connection.py:284(_send_bytes)

        1    0.000    0.000    0.000    0.000 context.py:197(get_start_method)

        1    0.000    0.000    0.000    0.000 context.py:237(get_context)

        1    0.000    0.000    0.000    0.000 context.py:65(Lock)

   250000    0.081    0.000    0.170    0.000 hashlib.py:152(__hash_new)

        1    0.000    0.000    0.000    0.000 process.py:37(current_process)

        1    0.000    0.000    0.000    0.000 random.py:480(choices)

        1    0.000    0.000    0.000    0.000 random.py:493(<listcomp>)

        1    0.000    0.000    0.000    0.000 random.py:808(randbytes)

        1    0.000    0.000    0.000    0.000 secrets.py:34(token_bytes)

        1    0.000    0.000    0.000    0.000 secrets.py:48(token_hex)

        1    0.000    0.000    0.000    0.000 shared_memory.py:185(__del__)

       11    0.000    0.000    0.000    0.000 shared_memory.py:204(buf)

        1    0.000    0.000    0.000    0.000 shared_memory.py:223(close)

        1    0.000    0.000    0.000    0.000 shared_memory.py:278(<lambda>)

        4    0.000    0.000    0.000    0.000 shared_memory.py:284(_extract_recreation_code)

        1    0.000    0.000    0.000    0.000 shared_memory.py:298(__init__)

        1    0.000    0.000    0.000    0.000 shared_memory.py:301(<listcomp>)

        4    0.000    0.000    0.000    0.000 shared_memory.py:310(<genexpr>)

        1    0.000    0.000    0.000    0.000 shared_memory.py:319(<listcomp>)

        4    0.000    0.000    0.000    0.000 shared_memory.py:346(<genexpr>)

        4    0.000    0.000    0.000    0.000 shared_memory.py:352(<genexpr>)

        2    0.000    0.000    0.000    0.000 shared_memory.py:371(_get_packing_format)

        1    0.000    0.000    0.000    0.000 shared_memory.py:387(_get_back_transform)

        1    0.000    0.000    0.000    0.000 shared_memory.py:40(_make_filename)

        1    0.000    0.000    0.000    0.000 shared_memory.py:402(_set_packing_format_and_transform)

        1    0.000    0.000    0.000    0.000 shared_memory.py:424(__getitem__)

        1    0.000    0.000    0.000    0.000 shared_memory.py:441(__setitem__)

        2    0.000    0.000    0.000    0.000 shared_memory.py:490(_format_size_metainfo)

        2    0.000    0.000    0.000    0.000 shared_memory.py:495(_format_packing_metainfo)

        2    0.000    0.000    0.000    0.000 shared_memory.py:500(_format_back_transform_codes)

       10    0.000    0.000    0.000    0.000 shared_memory.py:505(_offset_data_start)

        7    0.000    0.000    0.000    0.000 shared_memory.py:511(_offset_packing_formats)

        3    0.000    0.000    0.000    0.000 shared_memory.py:515(_offset_back_transform_codes)

        1    0.000    0.000    0.000    0.000 shared_memory.py:75(__init__)

        1    0.000    0.000    0.000    0.000 synchronize.py:121(_make_name)

        1    0.000    0.000    0.000    0.000 synchronize.py:168(__init__)

        1    0.000    0.000    0.000    0.000 synchronize.py:50(__init__)

        1    0.000    0.000    0.000    0.000 synchronize.py:90(_make_methods)

        1    0.000    0.000    0.000    0.000 synchronize.py:94(__enter__)

        1    0.000    0.000    0.000    0.000 synchronize.py:97(__exit__)

        1    0.000    0.000    0.000    0.000 tempfile.py:143(rng)

        1    0.000    0.000    0.000    0.000 tempfile.py:154(__next__)

        1    0.000    0.000    0.000    0.000 threading.py:1206(daemon)

        1    0.000    0.000    0.000    0.000 threading.py:1324(_make_invoke_excepthook)

        1    0.000    0.000    0.000    0.000 threading.py:1453(current_thread)

        1    0.000    0.000    0.000    0.000 threading.py:243(__init__)

        1    0.000    0.000    0.000    0.000 threading.py:271(__enter__)

        1    0.000    0.000    0.000    0.000 threading.py:274(__exit__)

        1    0.000    0.000    0.000    0.000 threading.py:280(_release_save)

        1    0.000    0.000    0.000    0.000 threading.py:283(_acquire_restore)

        1    0.000    0.000    0.000    0.000 threading.py:286(_is_owned)

        1    0.000    0.000    0.001    0.001 threading.py:295(wait)

        1    0.000    0.000    0.000    0.000 threading.py:562(__init__)

        1    0.000    0.000    0.000    0.000 threading.py:575(is_set)

        1    0.000    0.000    0.001    0.001 threading.py:611(wait)

        1    0.000    0.000    0.000    0.000 threading.py:811(_newname)

        1    0.000    0.000    0.000    0.000 threading.py:856(__init__)

        1    0.000    0.000    0.001    0.001 threading.py:945(start)

        1    0.000    0.000    0.000    0.000 util.py:48(debug)

   250000    0.088    0.000    0.088    0.000 {built-in method _hashlib.new}

        1    0.000    0.000    0.000    0.000 {built-in method _struct.calcsize}

        7    0.000    0.000    0.000    0.000 {built-in method _struct.pack_into}

        4    0.000    0.000    0.000    0.000 {built-in method _struct.unpack_from}

        2    0.000    0.000    0.000    0.000 {built-in method _thread.allocate_lock}

        1    0.000    0.000    0.000    0.000 {built-in method _thread.get_ident}

        1    0.000    0.000    0.000    0.000 {built-in method _thread.start_new_thread}

        1    0.000    0.000    0.000    0.000 {built-in method _winapi.CloseHandle}

        1    0.000    0.000    0.000    0.000 {built-in method _winapi.CreateFileMapping}

        1    0.000    0.000    0.000    0.000 {built-in method _winapi.GetLastError}

        1    0.000    0.000    0.000    0.000 {built-in method _winapi.WriteFile}

        1    0.000    0.000    0.000    0.000 {built-in method binascii.hexlify}

        1    0.000    0.000   10.606   10.606 {built-in method builtins.exec}

        1    0.000    0.000    0.000    0.000 {built-in method builtins.getattr}

       11    0.000    0.000    0.000    0.000 {built-in method builtins.isinstance}

        8    0.000    0.000    0.000    0.000 {built-in method builtins.len}

        1    0.000    0.000    0.000    0.000 {built-in method builtins.next}

        1    0.000    0.000    0.000    0.000 {built-in method builtins.sum}

        8    0.000    0.000    0.000    0.000 {built-in method math.floor}

        1    0.000    0.000    0.000    0.000 {built-in method nt.getpid}

        1    0.000    0.000    0.000    0.000 {built-in method nt.urandom}

        1    0.000    0.000    0.000    0.000 {method 'GetOverlappedResult' of '_winapi.Overlapped' objects}

        1    0.000    0.000    0.000    0.000 {method '__enter__' of '_multiprocessing.SemLock' objects}

        1    0.000    0.000    0.000    0.000 {method '__enter__' of '_thread.lock' objects}

        1    0.000    0.000    0.000    0.000 {method '__exit__' of '_multiprocessing.SemLock' objects}

        1    0.000    0.000    0.000    0.000 {method '__exit__' of '_thread.RLock' objects}

        1    0.000    0.000    0.000    0.000 {method '__exit__' of '_thread.lock' objects}

        4    0.001    0.000    0.001    0.000 {method 'acquire' of '_thread.lock' objects}

        1    0.000    0.000    0.000    0.000 {method 'add' of 'set' objects}

        1    0.000    0.000    0.000    0.000 {method 'append' of 'collections.deque' objects}

        3    0.000    0.000    0.000    0.000 {method 'append' of 'list' objects}

        1    0.000    0.000    0.000    0.000 {method 'close' of 'mmap.mmap' objects}

  8000000    1.404    0.000    1.404    0.000 {method 'copy' of '_hashlib.HASH' objects}

        3    0.000    0.000    0.000    0.000 {method 'decode' of 'bytes' objects}

  8000000    2.945    0.000    2.945    0.000 {method 'digest' of '_hashlib.HASH' objects}

        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

        4    0.000    0.000    0.000    0.000 {method 'encode' of 'str' objects}

   250000    0.033    0.000    0.033    0.000 {method 'join' of 'bytes' objects}

        3    0.000    0.000    0.000    0.000 {method 'join' of 'str' objects}

        8    0.000    0.000    0.000    0.000 {method 'random' of '_random.Random' objects}

        1    0.000    0.000    0.000    0.000 {method 'release' of '_thread.lock' objects}

        1    0.000    0.000    0.000    0.000 {method 'release' of 'memoryview' objects}

        1    0.000    0.000    0.000    0.000 {method 'rpartition' of 'str' objects}

        2    0.000    0.000    0.000    0.000 {method 'rstrip' of 'bytes' objects}

  8000000    0.661    0.000    0.661    0.000 {method 'update' of '_hashlib.HASH' objects}



Sha512 Hash: 0c0861dc3779cc1e7cc7b1edcdd1864617f3f4c67656724e47c94033ced9f1c0750807a20a7283df8cc52c27d3814fd5200d9ab27d308aaa7df550a70f155249

90725757 16.3540242 amongamongamong

         24750204 function calls in 12.229 seconds


   Ordered by: standard name


   ncalls  tottime  percall  cumtime  percall filename:lineno(function)

        1    0.000    0.000    0.000    0.000 <frozen importlib._bootstrap>:405(parent)

        1    0.000    0.000   12.228   12.228 <string>:1(<module>)

        1    0.000    0.000    0.000    0.000 MultiProcessorPipe2.py:17(__init__)

        1    5.357    5.357   12.228   12.228 MultiProcessorPipe2.py:27(run)

        1    0.000    0.000    0.000    0.000 _weakrefset.py:85(add)

        1    0.000    0.000    0.000    0.000 connection.py:135(_check_closed)

        1    0.000    0.000    0.000    0.000 connection.py:143(_check_writable)

        1    0.000    0.000    0.000    0.000 connection.py:182(send_bytes)

        1    0.000    0.000    0.000    0.000 connection.py:284(_send_bytes)

        1    0.000    0.000    0.000    0.000 context.py:197(get_start_method)

        1    0.000    0.000    0.000    0.000 context.py:237(get_context)

        1    0.000    0.000    0.000    0.000 context.py:65(Lock)

   250000    0.081    0.000    0.171    0.000 hashlib.py:152(__hash_new)

        1    0.000    0.000    0.000    0.000 process.py:37(current_process)

        1    0.000    0.000    0.000    0.000 random.py:480(choices)

        1    0.000    0.000    0.000    0.000 random.py:493(<listcomp>)

        1    0.000    0.000    0.000    0.000 random.py:808(randbytes)

        1    0.000    0.000    0.000    0.000 secrets.py:34(token_bytes)

        1    0.000    0.000    0.000    0.000 secrets.py:48(token_hex)

        1    0.000    0.000    0.000    0.000 shared_memory.py:185(__del__)

       11    0.000    0.000    0.000    0.000 shared_memory.py:204(buf)

        1    0.000    0.000    0.000    0.000 shared_memory.py:223(close)

        1    0.000    0.000    0.000    0.000 shared_memory.py:278(<lambda>)

        4    0.000    0.000    0.000    0.000 shared_memory.py:284(_extract_recreation_code)

        1    0.000    0.000    0.000    0.000 shared_memory.py:298(__init__)

        1    0.000    0.000    0.000    0.000 shared_memory.py:301(<listcomp>)

        4    0.000    0.000    0.000    0.000 shared_memory.py:310(<genexpr>)

        1    0.000    0.000    0.000    0.000 shared_memory.py:319(<listcomp>)

        4    0.000    0.000    0.000    0.000 shared_memory.py:346(<genexpr>)

        4    0.000    0.000    0.000    0.000 shared_memory.py:352(<genexpr>)

        2    0.000    0.000    0.000    0.000 shared_memory.py:371(_get_packing_format)

        1    0.000    0.000    0.000    0.000 shared_memory.py:387(_get_back_transform)

        1    0.000    0.000    0.000    0.000 shared_memory.py:40(_make_filename)

        1    0.000    0.000    0.000    0.000 shared_memory.py:402(_set_packing_format_and_transform)

        1    0.000    0.000    0.000    0.000 shared_memory.py:424(__getitem__)

        1    0.000    0.000    0.000    0.000 shared_memory.py:441(__setitem__)

        2    0.000    0.000    0.000    0.000 shared_memory.py:490(_format_size_metainfo)

        2    0.000    0.000    0.000    0.000 shared_memory.py:495(_format_packing_metainfo)

        2    0.000    0.000    0.000    0.000 shared_memory.py:500(_format_back_transform_codes)

       10    0.000    0.000    0.000    0.000 shared_memory.py:505(_offset_data_start)

        7    0.000    0.000    0.000    0.000 shared_memory.py:511(_offset_packing_formats)

        3    0.000    0.000    0.000    0.000 shared_memory.py:515(_offset_back_transform_codes)

        1    0.000    0.000    0.000    0.000 shared_memory.py:75(__init__)

        1    0.000    0.000    0.000    0.000 synchronize.py:121(_make_name)

        1    0.000    0.000    0.000    0.000 synchronize.py:168(__init__)

        1    0.000    0.000    0.000    0.000 synchronize.py:50(__init__)

        1    0.000    0.000    0.000    0.000 synchronize.py:90(_make_methods)

        1    0.000    0.000    0.000    0.000 synchronize.py:94(__enter__)

        1    0.000    0.000    0.000    0.000 synchronize.py:97(__exit__)

        1    0.000    0.000    0.000    0.000 tempfile.py:143(rng)

        1    0.000    0.000    0.000    0.000 tempfile.py:154(__next__)

        1    0.000    0.000    0.000    0.000 threading.py:1206(daemon)

        1    0.000    0.000    0.000    0.000 threading.py:1324(_make_invoke_excepthook)

        1    0.000    0.000    0.000    0.000 threading.py:1453(current_thread)

        1    0.000    0.000    0.000    0.000 threading.py:243(__init__)

        1    0.000    0.000    0.000    0.000 threading.py:271(__enter__)

        1    0.000    0.000    0.000    0.000 threading.py:274(__exit__)

        1    0.000    0.000    0.000    0.000 threading.py:280(_release_save)

        1    0.000    0.000    0.000    0.000 threading.py:283(_acquire_restore)

        1    0.000    0.000    0.000    0.000 threading.py:286(_is_owned)

        1    0.000    0.000    0.000    0.000 threading.py:295(wait)

        1    0.000    0.000    0.000    0.000 threading.py:562(__init__)

        1    0.000    0.000    0.000    0.000 threading.py:575(is_set)

        1    0.000    0.000    0.001    0.001 threading.py:611(wait)

        1    0.000    0.000    0.000    0.000 threading.py:811(_newname)

        1    0.000    0.000    0.000    0.000 threading.py:856(__init__)

        1    0.000    0.000    0.001    0.001 threading.py:945(start)

        1    0.000    0.000    0.000    0.000 util.py:48(debug)

   250000    0.090    0.000    0.090    0.000 {built-in method _hashlib.new}

        1    0.000    0.000    0.000    0.000 {built-in method _struct.calcsize}

        7    0.000    0.000    0.000    0.000 {built-in method _struct.pack_into}

        4    0.000    0.000    0.000    0.000 {built-in method _struct.unpack_from}

        2    0.000    0.000    0.000    0.000 {built-in method _thread.allocate_lock}

        1    0.000    0.000    0.000    0.000 {built-in method _thread.get_ident}

        1    0.000    0.000    0.000    0.000 {built-in method _thread.start_new_thread}

        1    0.000    0.000    0.000    0.000 {built-in method _winapi.CloseHandle}

        1    0.000    0.000    0.000    0.000 {built-in method _winapi.CreateFileMapping}

        1    0.000    0.000    0.000    0.000 {built-in method _winapi.GetLastError}

        1    0.000    0.000    0.000    0.000 {built-in method _winapi.WriteFile}

        1    0.000    0.000    0.000    0.000 {built-in method binascii.hexlify}

        1    0.000    0.000   12.229   12.229 {built-in method builtins.exec}

        1    0.000    0.000    0.000    0.000 {built-in method builtins.getattr}

       11    0.000    0.000    0.000    0.000 {built-in method builtins.isinstance}

        8    0.000    0.000    0.000    0.000 {built-in method builtins.len}

        1    0.000    0.000    0.000    0.000 {built-in method builtins.next}

        1    0.000    0.000    0.000    0.000 {built-in method builtins.sum}

        8    0.000    0.000    0.000    0.000 {built-in method math.floor}

        1    0.000    0.000    0.000    0.000 {built-in method nt.getpid}

        1    0.000    0.000    0.000    0.000 {built-in method nt.urandom}

        1    0.000    0.000    0.000    0.000 {method 'GetOverlappedResult' of '_winapi.Overlapped' objects}

        1    0.000    0.000    0.000    0.000 {method '__enter__' of '_multiprocessing.SemLock' objects}

        1    0.000    0.000    0.000    0.000 {method '__enter__' of '_thread.lock' objects}

        1    0.000    0.000    0.000    0.000 {method '__exit__' of '_multiprocessing.SemLock' objects}

        1    0.000    0.000    0.000    0.000 {method '__exit__' of '_thread.RLock' objects}

        1    0.000    0.000    0.000    0.000 {method '__exit__' of '_thread.lock' objects}

        4    0.000    0.000    0.000    0.000 {method 'acquire' of '_thread.lock' objects}

        1    0.000    0.000    0.000    0.000 {method 'add' of 'set' objects}

        1    0.000    0.000    0.000    0.000 {method 'append' of 'collections.deque' objects}

        3    0.000    0.000    0.000    0.000 {method 'append' of 'list' objects}

        1    0.000    0.000    0.000    0.000 {method 'close' of 'mmap.mmap' objects}

  8000000    1.412    0.000    1.412    0.000 {method 'copy' of '_hashlib.HASH' objects}

        3    0.000    0.000    0.000    0.000 {method 'decode' of 'bytes' objects}

  8000000    4.549    0.000    4.549    0.000 {method 'digest' of '_hashlib.HASH' objects}

        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

        4    0.000    0.000    0.000    0.000 {method 'encode' of 'str' objects}

   250000    0.035    0.000    0.035    0.000 {method 'join' of 'bytes' objects}

        3    0.000    0.000    0.000    0.000 {method 'join' of 'str' objects}

        8    0.000    0.000    0.000    0.000 {method 'random' of '_random.Random' objects}

        1    0.000    0.000    0.000    0.000 {method 'release' of '_thread.lock' objects}

        1    0.000    0.000    0.000    0.000 {method 'release' of 'memoryview' objects}

        1    0.000    0.000    0.000    0.000 {method 'rpartition' of 'str' objects}

        2    0.000    0.000    0.000    0.000 {method 'rstrip' of 'bytes' objects}

  8000000    0.703    0.000    0.703    0.000 {method 'update' of '_hashlib.HASH' objects}



Enter Password: q

Done

Final Submission

With the deadline quickly approaching I ended my optimization journey with one last optimization. As part of this assignment we were allowed to use the length of the inputted password to quickly decrypt it. I believe we were allowed to do this since the intended solution was to iterate through every possible combination and this would significantly speed up the process. An example of this is in the first attempt were after using the length with the soon to be mentioned optimizations turned the ~3 minute run time to around ~11 seconds. Said other optimizations were also sorting the word list by length before trying to decrypt it as this let me possible removed all permutations and even skip over processes. The last change was also adding the graphing portion of the assignment. In terms of performance the length filter makes it extremely difficult to know which word combination takes the longest however I have not seen any take more then 10 seconds and the longest was ~8 seconds which was easteasteast.

Final Submission Code

import itertools

import hashlib

import multiprocessing.shared_memory

import matplotlib.pyplot as plt

import matplotlib

import time

import multiprocessing 

import threading

import cProfile #Used for profiling

import math

from multiprocessing import shared_memory

import sys


#An Iterative approch to the problem however is not used due to a faster implmentation

def hashAttack(wordLimit: int, words: list, password: bytes, algorithm: str, passwordLen : int):

    start = time.time_ns()

    minLen = len(words[0])

    maxLen = len(words[-1])

    count = 0

    for i in range(1, wordLimit + 1):        

        if not isBetween(minLen * (i + 1), passwordLen, maxLen * (i + 1)):

            continue

        perms = itertools.product(words, repeat=i)

        for p in perms:

            test = b''.join(p)

            if passwordLen != len(test):

                continue

            hash = hashlib.new(algorithm)

            hash.update(test)

            count += 1

            if (hash.digest() == password):

                return count, (time.time_ns() - start) / 1e9, test.decode()

    return None, None


#Converges the geometric series for when starting at 1

def geometricSeries(a: int, r: int, n: int):

    return a * r * ((r ** n - 1) // (r - 1))


#Will return if the value is in between two other values, inclusive

def isBetween(min, val, max):

    return min <= val and val <= max


#Used as a shared boolean between process and thread

class CancellationToken:

   def __init__(self):

       self.is_cancelled = False


   def cancel(self):

       self.is_cancelled = True


#Will wait until a provided event is trigered then sets the token to True

def wait(event, token):

    event.wait()

    token.cancel()


#Takes a chunk of data then tests to see if any are the password, will stop when the event is set

def run(perms, arr, algorithm, password, words, lock, conn, event, passwordLen):

    count = 0

    token = CancellationToken()

    thread = threading.Thread(target=wait, args=[event, token]) #Starts the thread to see if the event is set

    thread.start()

    minLen = len(words[0])

    maxLen = len(words[-1])

    #For ever previous permutation

    for p in perms:

        word = b''.join(p)

        if not isBetween(len(word) + minLen, passwordLen, len(word) + maxLen):

            continue

        #Add each word to the end

        for w in words:

            test = word + w

            if passwordLen != len(test):

                continue

            hash = hashlib.new(algorithm, test)

            count += 1

            if hash.digest() == password:

                event.set() #Tells all other process to end

                with lock:

                    arr[2] = test

                    arr[1] = True

            elif token.is_cancelled: break

        if token.is_cancelled: break

    with lock:

        arr[0] = arr[0] + count

        conn.send_bytes(b'\x00') #Signal that the process has ended

    thread.join() #Waits for the thread to end


#Takes a list of words and a hashed password and will try to decode said password

def multiProcessor2(wordLimit: int, words: list, password: bytes, algorithm: str, passwordLen : int):

    start = time.time_ns()

    minLen = len(words[0])

    maxLen = len(words[-1])

    arr = shared_memory.ShareableList([0, False, "\0" * (maxLen * wordLimit)]) #Shared output among process

    lock = multiprocessing.Lock() #Shared lock among process to acess the shared output safely

    recv, send = multiprocessing.Pipe() #Signal to know when a process finishes

    event = multiprocessing.Event() #Event to tell all process to finish

    #For every wordlimt

    for i in range(0, wordLimit):

        if not isBetween(minLen * (i + 1), passwordLen, maxLen * (i + 1)):

            continue

        perms = itertools.product(words, repeat = i) #Get all permutations of the previous wordlimt

        wordsLen = len(words)

        size = math.ceil(wordsLen / multiprocessing.cpu_count()) #Chunk length of words to split

        processes = [] #Holds all the processes

        for j in range(0, wordsLen, size):

            subArr = words[j : j + size]

            if not isBetween((minLen * i) + len(subArr[0]), passwordLen, (maxLen * i) + len(subArr[-1])):

                continue

            p = multiprocessing.Process(target=run,args=[perms, arr, algorithm, password, subArr, lock, send, event, passwordLen])

            p.start()

            processes.append(p)

            if arr[1]: break #If found

            

        completed = 0 #Counts how many processes have finished

        while completed != len(processes):

            recv.recv_bytes() #Waits until a process finishes

            if arr[1]: #If value is found

                break

            completed += 1


        event.set() #Tells all the processes to finish

        #Waits until all process have finished

        for p in processes:

            p.join()

        event.clear() #Resets the event to do again if needed

        if arr[1]:

            break

    #Close Connections

    recv.close()

    send.close()

    return arr[0], (time.time_ns() - start) / 1e9, arr[2].decode() #returns (count, time, password)


#Takes a password and hash algorithm and will try to break it

def codeAndDecode(algorithm, password, wordLimit, words, passwordLen, printing=False):   

    hash = hashlib.new(algorithm)

    hash.update(password) #Hashes the password

    if printing:

        print(f"{algorithm.capitalize()} Hash: {hash.hexdigest()}") #Prints nice Hex

    return multiProcessor2(wordLimit, words, hash.digest(), algorithm, passwordLen)  


#Takes a axis and will add data to it depending on the type

def setUpAxes(data, type, ax):

    index = -1

    if type == 'Count':

        index = 0

    elif type == 'Time (sec)':

        index = 1

    data = sorted(data, key = lambda x: x[-1]) #Sorts data based on complexity

    x = []

    y = []

    for i in range(0, len(data)):

        d = data[i]

        x.append(i + 1)

        y.append(d[index])

    ax.plot(x,y,'o-')


#Main function

if __name__ == "__main__":

    wordLimit = 3

    dictonaryName = "MediumDictionary.txt"

    hashAlgorithms = list(hashlib.algorithms_available) #Comment the line below to see all hashes

    hashAlgorithms = ['sha256', 'sha512']

    hashAlgorithms = [h for h in hashAlgorithms if "shake" not in h] #Removed shake hashes which require a length to hash

    f = open(dictonaryName, "r")

    words = f.read().splitlines() #Reads the dictonary

    f.close()

    words = sorted(words, key=len) #Sorts the dictonary


    data = [[] for _ in hashAlgorithms] #Initializes data

    perms = ["".join(p) for i in range(1, wordLimit + 1) for p in itertools.product(words, repeat=i)] #Combines all possible iterations, I know this isn't memory efficent but is better then doing iterativly for how often I use it

    password = input("Enter Password: ")

    words = [w.encode() for w in words] #Encodes all the words to bytes

    #While the user is inputting passwords

    while password != "q":

        count = perms.index(password) + 1 #Get the complexity

        password = password.encode()

        #Decodes the password using different algorithms

        for i in range(0, len(hashAlgorithms)):

            ret = codeAndDecode(hashAlgorithms[i], password, wordLimit, words, len(password), True) + (count,)

            data[i].append(ret)

            print(ret)

        password = input("Enter Password: ")


    inputedData = data[0].copy() #Copies the data 

    count = 0

    total = len(inputedData) * 10 * len(hashAlgorithms) #How much data will be calculated, used for percentage

    for a in range(0, len(inputedData)):

        d = inputedData[a] #Gets the data

        #For every value that is 5 to the left and 5 to the right

        for i in range(d[-1] - 5, d[-1] + 6):

            if i == d[-1]: #Not current value

                continue

            password = perms[i - 1].encode()

            index = perms.index(perms[i - 1]) + 1 #Get the complexity

            for j in range(0, len(hashAlgorithms)):

                count += 1

                ret = codeAndDecode(hashAlgorithms[j], password, wordLimit, words, len(password)) + (index,)

                data[j].append(ret)

                #Prints the percentage

                sys.stdout.write(f"\rComputing Specific Values Currently: {round(count / total * 100,2)}%")

                sys.stdout.flush()

    print() #Resets printing to function properly


    #Makes all the plots

    fig, axs = plt.subplots(ncols=2, nrows=1, layout='constrained')

    axs = axs.flatten()

    ylabels = ['Time (sec)', 'Count']

    for a in range(0, len(axs)):

        ax = axs[a]

        label = ylabels[a]

        ax.set_title(f"Complexity vs. {label} to Crack Different Hashes with a Dictonary Size of {len(words)}")

        ax.grid(False)

        ax.set_xlabel("Complexity")

        ax.set_ylabel(label)

        ax.set_xticks(list(range(1, len(data[0]) + 1)))

        ax.set_xticklabels([d[2] for d in sorted(data[0], key = lambda x: x[-1])], rotation='vertical')

        for i in range(0, len(hashAlgorithms)):

            algorithm = hashAlgorithms[i]

            setUpAxes(data[i], label, ax)

    fig.legend(loc='outside center right', labels=hashAlgorithms) #The legend of the plots

    plt.ticklabel_format(style='plain', axis='y') #Removes the 1e6 from the graphs

    plt.show(block=True) #Shows the plots


    print("Done") 

Documentation

Documentation.pdf

Output Graphs

All Files

Google Sites
Report abuse
Page details
Page updated
Google Sites
Report abuse