Modyfikacja prostego skryptu

0

Witam,
Mam skrypt który na podstawie wprowadzonej wartości generuje losowe kombinacje i sprawdza czy wynik jest właściwy. Jeżeli tak - zapisuje wartość i wynik do pliku... Oto on:

import random
from bit import *
from PyRandLib import *
rand = FastRand63()
random.seed(rand())

c1 = str (random.choice("1"))
b1  = "01111111111111111111111111111111111111111111111111111111" # pierwszy zestaw mieszania (kombinacje jednego zera i 55x jedynek)
b2  = "00111111111111111111111111111111111111111111111111111111" # drugi zestaw mieszania   itd....
b3  = "00011111111111111111111111111111111111111111111111111111" 
b4  = "00001111111111111111111111111111111111111111111111111111" 
b5  = "00000111111111111111111111111111111111111111111111111111" 
b6  = "00000011111111111111111111111111111111111111111111111111" 
b7  = "00000001111111111111111111111111111111111111111111111111" 
b8  = "00000000111111111111111111111111111111111111111111111111" 
b9  = "00000000011111111111111111111111111111111111111111111111" 
#xx = "0000000000000000000000000000000000000000000000001"

while True:
    spisok = [b1,b2,b3,b4,b5,b6,b7,b8,b9]
    for element in (spisok):
        for spisok in range(1000):
            s = element
            d = ''.join(random.sample(s,len(s)))
            bina = (c1+d)
            b = int(c1+d,2)
            key = Key.from_int(b)
            addr = key.address
            if addr == "1HBAiS8FKAeBVNubKApKM1pFamT5RKojP2": # przykładowa wartość do której szukam właściwego ciągu  
                print ("found!!!",b,addr)
                s1 = str(b)
                s2 = addr
                f=open(u"C:/a.txt","a")
                f.write(s1)
                f.write(s2)       
                f.close()
                pass
            else:
                print (s,bina,b,addr)
    pass

W jaki sposób mogę go zmodyfikować aby zamiast tworzyć losowe wartości od podanych zakresów w polach b1-b9 -> skrypt szukał wyniku sprawdzając po kolei od tej wartości każdą jedną możliwość. Byłoby w ten sposób łatwiej stwierdzić poziom postępu w szukaniu. Dziękuję za pomoc i przy okazji - szczęśliwego nowego roku ! :-)

2
  1. Zacznijmy może od tego
c1 = str (random.choice("1"))

choice() ze stringa też zwróci ci stringa, także to rzutowanie jest tam zbędne.
Sprawa druga - po cóż robisz tam randoma z jednoznakowego stringa - przecież zawsze będzie on taki sam - '1'.
Więc ta linijka jest kompletnie zbędna i można by ją zastąpić po prostu:

c1 = '1'
  1. Następna rzecz:
b1  = "01111111111111111111111111111111111111111111111111111111" # pierwszy zestaw mieszania (kombinacje jednego zera i 55x jedynek)
b2  = "00111111111111111111111111111111111111111111111111111111" # drugi zestaw mieszania   itd....
b3  = "00011111111111111111111111111111111111111111111111111111"
b4  = "00001111111111111111111111111111111111111111111111111111"
b5  = "00000111111111111111111111111111111111111111111111111111"
b6  = "00000011111111111111111111111111111111111111111111111111"
b7  = "00000001111111111111111111111111111111111111111111111111"
b8  = "00000000111111111111111111111111111111111111111111111111"
b9  = "00000000011111111111111111111111111111111111111111111111"
#xx = "0000000000000000000000000000000000000000000000001"

mam nadzieję, że ręcznie tego nie pisałeś...
zastąpmy to następującym kodem:

sets_length = 56
mix_sets = ["0"*i+"1"*(sets_length-i) for i in range(sets_length)]

Czy też może w tym wypadku jaśniej by było:

import itertools
sets_length = 56
mix_sets = list(itertools.combinations_with_replacement('01', sets_length))

Jeśli chcesz tylko pierwsze 9 elementów, to cyk:

first_9_mix_sets = mix_sets[:9]

Chociaż ten kod i tak jest zbędny moim zdaniem, bo
Z tego, co rozumiem dalej:

for spisok in range(1000):
            s = element
            d = ''.join(random.sample(s,len(s)))

To wychodzi na to, że tak w rzeczywistości masz jakiś tam klucz o długości 56 bitów.
Może on zawierać dowolną liczbę zer lub jedynek w dowolnej kolejności. I teraz na podstawie takiego klucza chcesz odgadywać inny klucz?
Ja przynajmniej mniej więcej tak rozumiem twój kod.
Jeśli tak jest, to nie mam dobrych wiadomości, bo wtedy masz 2^56 możliwości do sprawdzenia, więc powodzenia.
Ale by wyświetlić progres, możesz zasugerować się czymś takim:

import itertools
for index, element in enumerate(itertools.product('01', 56)):
            d = ''.join(random.sample(element,len(element)))
            bina = (c1+d)
            b = int(c1+d,2)
            key = Key.from_int(b)
            addr = key.address
            if addr == "1HBAiS8FKAeBVNubKApKM1pFamT5RKojP2": # przykładowa wartość do której szukam właściwego ciągu  
                print ("found!!!",b,addr)
                s1 = str(b)
                s2 = addr
                f=open(u"C:/a.txt","a")
                f.write(s1)
                f.write(s2)       
                f.close()
                break
            print(f'progress: {index/(2**56)*100}%')

Przy czym ten kod będzie się wykonywał wieki.

W innym wypadku, podaj proszę może więcej szczegółów co do tego, co ma robić twój kod.

0
grski napisał(a):
  1. Zacznijmy może od tego
c1 = str (random.choice("1"))

choice() ze stringa też zwróci ci stringa, także to rzutowanie jest tam zbędne.
Sprawa druga - po cóż robisz tam randoma z jednoznakowego stringa - przecież zawsze będzie on taki sam - '1'.
Więc ta linijka jest kompletnie zbędna i można by ją zastąpić po prostu:

c1 = '1'
  1. Następna rzecz:
b1  = "01111111111111111111111111111111111111111111111111111111" # pierwszy zestaw mieszania (kombinacje jednego zera i 55x jedynek)
b2  = "00111111111111111111111111111111111111111111111111111111" # drugi zestaw mieszania   itd....
b3  = "00011111111111111111111111111111111111111111111111111111"
b4  = "00001111111111111111111111111111111111111111111111111111"
b5  = "00000111111111111111111111111111111111111111111111111111"
b6  = "00000011111111111111111111111111111111111111111111111111"
b7  = "00000001111111111111111111111111111111111111111111111111"
b8  = "00000000111111111111111111111111111111111111111111111111"
b9  = "00000000011111111111111111111111111111111111111111111111"
#xx = "0000000000000000000000000000000000000000000000001"

mam nadzieję, że ręcznie tego nie pisałeś...
zastąpmy to następującym kodem:

sets_length = 56
mix_sets = ["0"*i+"1"*(sets_length-i) for i in range(sets_length)]

Czy też może w tym wypadku jaśniej by było:

import itertools
sets_length = 56
mix_sets = list(itertools.combinations_with_replacement('01', sets_length))

Jeśli chcesz tylko pierwsze 9 elementów, to cyk:

first_9_mix_sets = mix_sets[:9]

Chociaż ten kod i tak jest zbędny moim zdaniem, bo
Z tego, co rozumiem dalej:

for spisok in range(1000):
            s = element
            d = ''.join(random.sample(s,len(s)))

To wychodzi na to, że tak w rzeczywistości masz jakiś tam klucz o długości 56 bitów.
Może on zawierać dowolną liczbę zer lub jedynek w dowolnej kolejności. I teraz na podstawie takiego klucza chcesz odgadywać inny klucz?
Ja przynajmniej mniej więcej tak rozumiem twój kod.
Jeśli tak jest, to nie mam dobrych wiadomości, bo wtedy masz 2^56 możliwości do sprawdzenia, więc powodzenia.
Ale by wyświetlić progres, możesz zasugerować się czymś takim:

import itertools
for index, element in enumerate(itertools.product('01', 56)):
            d = ''.join(random.sample(element,len(element)))
            bina = (c1+d)
            b = int(c1+d,2)
            key = Key.from_int(b)
            addr = key.address
            if addr == "1HBAiS8FKAeBVNubKApKM1pFamT5RKojP2": # przykładowa wartość do której szukam właściwego ciągu  
                print ("found!!!",b,addr)
                s1 = str(b)
                s2 = addr
                f=open(u"C:/a.txt","a")
                f.write(s1)
                f.write(s2)       
                f.close()
                break
            print(f'progress: {index/(2**56)*100}%')

Przy czym ten kod będzie się wykonywał wieki.

W innym wypadku, podaj proszę może więcej szczegółów co do tego, co ma robić twój kod.

Ten skrypt nie działa pod Pythonem 3.7.2:

import random
import itertools
from bit import *
from PyRandLib import *
rand = FastRand63()
random.seed(rand())

import itertools
sets_length = 56
mix_sets = list(itertools.combinations_with_replacement('01', sets_length))

for spisok in range(1000):
   s = element
   d = ''.join(random.sample(s,len(s)))

for index, element in enumerate(itertools.product('01', 56)):
            d = ''.join(random.sample(element,len(element)))
            bina = (c1+d)
            b = int(c1+d,2)
            key = Key.from_int(b)
            addr = key.address
    if addr == "1HBAiS8FKAeBVNubKApKM1pFamT5RKojP2":
            print ("found!!!",b,addr)
            s1 = str(b)
            s2 = addr
            f=open(u"C:/a.txt","a")
            f.write(s1)
            f.write(s2)       
            f.close()
            break
            print(f'progress: {index/(2**56)*100}%')

Ciągle wyrzuca mi syntax error lub 'int' is not iterable

Dokładniej rzecz ujmując mam do znalezienia w ramach rozwiazania zagadki trzy klucze do adresów którego przykład podałem (1HBAiS8FKAeBVNubKApKM1pFamT5RKojP2) . Przeliczanie całych zakresów na pewno trwaloby wieki, ale ze mam podany konkretny zakres przedziałów DEC i mam an tyle sprzętu aby za kazdym odpalić wbrany - mniejszy zakres - że mogę się tego podjąć :-)
Jako że DOŁĄCZAM do zagadki ktora juz miala wczesniej rozwiazane kolejne kroki, wiem też że kolejny zakres zwieksza sie i jeden "keyspace" i tak oto BIN dla ostatnich rozwiazan wygladal nastepujaca:

0000 0000 0010 0011 0110 1111 1011 0110 1101 0101 1010 1101 0001 1111 0100 0110
0000 0000 0110 1010 1011 1110 0001 1111 1001 1011 0110 0111 1110 0001 0001 0100
0000 0000 1001 1101 0001 1000 1011 0110 0011 1010 1100 0100 1111 1111 1101 1111
0000 0001 1110 1011 0010 0101 1100 1001 0000 0111 1001 0101 1101 0110 0001 1100
0000 0010 1100 0110 0111 0101 1011 1000 0101 0010 0001 1000 1001 1010 0010 0001

więc nastpne rozwiązania będą miały rozwiązanie w zakresach kolejno:
0000 01xx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx #58
0000 1xxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx #59
0001 xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx #60

Widać więc skąd wynika stała wartość c1 = '1' (rozwiązania będą z przestrzeni 58, 59 i 60 i zaczynały od "1" w binarnej formie)
Stąd też dla mnie istotne jest stałe "1" , możliwość regulowania ilości zer i jedynek w rozwiazaniu oraz sprawdzenie kazdej opcji [ na kazdej maszynie ustawie inny stosunek zer do jedynek i kazda bedzie sprawdzala osobne przedzialy ]. Nie bez powodu też używany jest moduł "bit" który jest nieco bardziej sprawny w stosunku do konkurentów.
Bardzo dziękuję za pomoc już dotychczasową ... bardzo duży wkład widzę autora odpowiedzi :-) dziękuję z całych sił za to!

0

Możesz wkleić treść błędu całą i kod po modyfikacji?

0
grski napisał(a):

Możesz wkleić treść błędu całą i kod po modyfikacji?

import random
from bit import *
from PyRandLib import *
rand = FastRand63()
random.seed(rand())
import itertools
from itertools import *

sets_length = 56
mix_sets = list(itertools.combinations_with_replacement('01', sets_length))
c1 = '1'
b1  = mix_sets[:9]

while True:
    for index, element in enumerate(itertools.product('01', 56)):
            d = ''.join(random.sample(element,len(element)))
            bina = (c1+d)
            b = int(c1+d,2)
            key = Key.from_int(b)
            addr = key.address
            if addr == "1HBAiS8FKAeBVNubKApKM1pFamT5RKojP2": # przykładowa wartość do której szukam właściwego ciągu  
                print ("found!!!",b,addr)
                s1 = str(b)
                s2 = addr
                f=open(u"C:/a.txt","a")
                f.write(s1)
                f.write(s2)       
                f.close()
                break
            print(f'progress: {index/(2**56)*100}%')
    pass

I błąd:

Traceback (most recent call last):
File "tst.py", line 15, in <module>
for index, element in enumerate(itertools.product('01', 56)):
TypeError: 'int' object is not iterable

Jeszcze jedno pytanie... czy z pomocą pakietu Anaconda z numba, cudatoolkit, pyculib będzie możliwość zaangażować GPU do wykonywania tego skryptu?

0

@zielar:
sory, my bad
ten kawałek : itertools.product('01', 56)
powinien wyglądać tak: itertools.product('01', repeat=56)
To raz.
Dwa - wyrzuć:
d = ''.join(random.sample(element,len(element))) - nie ma potrzeby tego mixować bo linijka wyżej da ci naprawdę wszystkie możliwe kombinacje.

poza tym możesz wywalić tego while bo to itertools.product('01', repeat=56) da wszystkie możliwości
tak samo jak ten pass na końcu - raczej ci on niepotrzebny
no i na moje rozumowanie to ten 'c1' też powinien zostać usunięty z kodu

poza tym jeśli wiesz, że klucz zaczyna się albo ma określoną ilość 1 lub 0, to zajrzyj do postu pierwszego który napisałem, bo tutaj przerobisz WSZYSTKIE możliwości, a tak to możesz sobie trochę przypadków skrócić

sets_length = 56
mix_sets = list(itertools.combinations_with_replacement('01', sets_length))
c1 = '1'
b1  = mix_sets[:9]

no i ten fragment wyżej - połączyłeś dwa rozwiązania, niepotrzebnie
w tym kodzie akurat to możesz w zasadzie usunąć i nic się nie zmienic, chociaż jak wspomniałem, jeśli wiesz, że kod zaczyna się od określonej sekwencji to można do teog inaczej podejść

mianowicie, jeśli wiesz, że klucz będzie zaczynał się od 0000 01, to możesz zrobić coś takiego:
itertools.product('01', 50)

a potem:
zamiast tego d z randomem to:

d = '000001'+element
0

Teraz mi wywala

File "new.py", line 15
d = '000001'+element
^
TabError: inconsistent use of tabs and spaces in indentation

Już się pogubiłem. :-)
Wiadomo mi na temat następnego rozwiązania:
a) klucz znajduje się w przestrzeni 2^59 czyli w przedziałach:
HEX: 400000000000000-7FFFFFFFFFFFFFFFF
DEC: 288230376151711744-576460752303423487
BIN: 0000 01xx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx

liczby dokładej ile będzie jedynek i zer nie wiem, ale jeśli jakoś przyspieszyło by to szukanie rozwiązania to byłoby idealnym narzędziem do pogrupowania zadań na kilka maszyn (stosunek zer do jedynek dotychczas był pół na pół lub z niewielką przewagą [28-29, 27-29, 31-27 etc]
Co w tym przypadku więc finalnie będzie najlepsze?

0

No ten błąd akurat jest bardzo logiczny - w jednych miejscach masz taby a w innych spacje jako wcięcia - sprawdź to...

BIN: 0000 01xx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx

Ok, to faktycznie, zostaw 56 i tę jedynkę z przodu. Poza tym musisz przemyśleć, czy klucz ma być liczony ze string (zależy od treści zagadki)a, jeśli tak, to trzeba uwzględnić te początkowe zera. Jeśli z liczby, to nie, tylko wtedy trzeba pamiętać o tym, by zcastować tego stringa na inta.

0

tylko, że ja tego BINa podałem dla wiadomości. Nie podaję go przecież nigdzie w skrypcie.

0

Przede wszystkim powinieneś pokazać jak wygląda plik bit.py, a w szczególności, klasa Key.

Poza tym, skoro znasz zakres, to zamiast iterować po ciągach binarnych i konwertować je na inty, zwyczajnie przejdź się po range.

0
enedil napisał(a):

Przede wszystkim powinieneś pokazać jak wygląda plik bit.py, a w szczególności, klasa Key.

Poza tym, skoro znasz zakres, to zamiast iterować po ciągach binarnych i konwertować je na inty, zwyczajnie przejdź się po range.

bit.py:

import random
import bit
import PyRandLib
import itertools
from itertools import *
from bit import *
from PyRandLib import *
rand = FastRand63()
random.seed(rand())

sets_length = 56
mix_sets = list(itertools.combinations_with_replacement('01', sets_length))
c1 = '1'
b1 = mix_sets[:9]

while True:
    for index, element in enumerate(itertools.product('01', 56)):
            d = ''.join(random.sample(element, len(element)))
            bina = (c1+d)
            b = int(c1+d, 2)
            key = Key.from_int(b)
            addr = key.address
            if addr == "1HBAiS8FKAeBVNubKApKM1pFamT5RKojP2":
                print ("found!!!", b, addr)
                s1 = str(b)
                s2 = addr
                f = open(u"C:/a.txt", "a")
                f.write(s1)
                f.write(s2)
                f.close()
                break
            print(f'progress: {index/(2**56)*100}%')
    pass

Na range można przejść, ale nie działa mi to na int więc nie wiem jak się za to zabrać

0

Tu w bit.py importujesz bit? Chodzi mi o ten plik co zawiera opis klasy Key.

No i miej litość, nie stosuj from jakiś_moduł import *, bo później nie wiadomo zupełnie co jest skąd.

0
enedil napisał(a):

Tu w bit.py importujesz bit? Chodzi mi o ten plik co zawiera opis klasy Key.

No i miej litość, nie stosuj from jakiś_moduł import *, bo później nie wiadomo zupełnie co jest skąd.

Wszystko składa się tylko na ten jeden plik.
BIT to moduł do pythona ( jego opis jest tu: https://github.com/ofek/bit )

0

No to sprawdź teraz jak wiele iteracji w ciągu sekundy osiągasz. Z tego możesz wykliczyć sobie oczekiwany czas (pewnie przynajmniej 10000 godzin). Zbadaj co zajmuje najwięcej czasu, np tak:

python3 -m cProfile -s tottime ./skrypt.py

Po tym zastanów się jakie operacje są niepotrzebne, wyrzuć je. Jak skończysz, zacznij taki proces optymalizacji od nowa. Dopiero jak nie będzie już czego optymalizować, można myśleć o przepisaniu na GPU. Mała podpowiedź jeszcze: nie ograniczaj się do optymalizowania własnego kodu.

0

OK. Po przemyśleniach finalnie zrobiłem to w ten sposób:

from bit import *
import random

while 1 == 1:
    a = 288230376151711744
    while a <= 576460752303423488:
        bina = bin(a)[2:]
        zeros = bina.count("0")
        if zeros >= 26:
            if zeros <= 34:
                key = Key.from_int(a)
                addr = key.address
                if addr == "1EhqbyUMvvs7BfL8goY6qcPbD6YKfPqb7e":
                    print("found!!!", a, addr)
                    s1 = str(a)
                    s2 = addr
                    f = open(u"C:/a.txt", "a")
                    f.write(s1)
                    f.write(s2)
                    f.close()
                    break
                else:
                        print (a, bina, addr, zeros)
        a = a + 1
    pass

Kto mógłby mi pomóc w kwestii kompilacji na GPU? Nie mam kompletnie zielonego pojęcia na ten temat poza tym, że wiem o potrzebnych "numba, numpy itd. :-)
I w dalszym ciągu sprawia mi kłopot wdrożenie do tego "paska postępu" żeby było wiadomo cokolwiek :-)

Dzięki za wszelkie dotychczasowe sugestie

0

A te dwa z czego wynikają?

       if zeros >= 26:
            if zeros <= 34:
0
enedil napisał(a):

A te dwa z czego wynikają?

       if zeros >= 26:
            if zeros <= 34:

A te dwa to wynikają ze statystycznego punktu widzenia na poprzednie rozwiązania... Liczba zer w ciągu BIN będzie się w tym przedziale mieściła 90%

1 użytkowników online, w tym zalogowanych: 0, gości: 1