11from __future__ import print_function
2- from __future__ import division
3- import os ,sys ,struct ,glob
4- from binascii import hexlify , unhexlify
2+ import os ,sys ,struct ,glob ,urllib2
53
64#don't change this mid brute force - can be different amount multiple computers - powers of two recommended for even distribution of workload 1 2 4 8 etc.
75process_count = 4
2119err_correct = 0
2220
2321def int16bytes (n ):
24- if sys .version_info [0 ] > 2 :
25- # Python 3
26- return n .to_bytes (16 , 'big' )
27- else :
28- # Python 2
29- s = b""
30- for i in range (16 ):
31- s = chr (n & 0xFF )+ s
32- n = n >> 8
33- return s
22+ s = ""
23+ for i in range (16 ):
24+ s = chr (n & 0xFF )+ s
25+ n = n >> 8
26+ return s
3427
3528def expand ():
3629 for i in range (1 ,len (lfcs )):
@@ -82,20 +75,22 @@ def getMsed3Estimate(n,isNew):
8275 xl = (fc [i ]- fc [i - 1 ])
8376 y = ft [i - 1 ]
8477 yl = (ft [i ]- ft [i - 1 ])
85- ys = ((xs * yl )// xl )+ y
78+ ys = ((xs * yl )/ xl )+ y
8679 err_correct = ys
87- return ((n // 5 )- ys ) | newbit
80+ return ((n / 5 )- ys ) | newbit
8881
89- return ((n // 5 )- ft [ft_size - 1 ]) | newbit
82+ return ((n / 5 )- ft [ft_size - 1 ]) | newbit
9083
9184def mii_gpu ():
9285 from Cryptodome .Cipher import AES
9386
9487 nk31 = 0x59FC817E6446EA6190347B20E9BDCE52
9588 with open ("input.bin" , "rb" ) as f :
9689 enc = f .read ()
97-
98- nonce = enc [:8 ]+ b"\x00 " * 4
90+ if (len (enc ) != 0x70 ):
91+ print ("Error: input.bin is invalid size (likely QR -> input.bin conversion issue)" )
92+ sys .exit (0 )
93+ nonce = enc [:8 ]+ "\x00 " * 4
9994 cipher = AES .new (int16bytes (nk31 ), AES .MODE_CCM , nonce )
10095 dec = cipher .decrypt (enc [8 :0x60 ])
10196 nonce = nonce [:8 ]
@@ -108,16 +103,16 @@ def mii_gpu():
108103 else :
109104 print ("Error: need to specify new|old movable.sed" )
110105 sys .exit (0 )
111- model_str = b ""
112- start_lfcs_old = 0x0B000000 // 2
113- start_lfcs_new = 0x05000000 // 2
106+ model_str = ""
107+ start_lfcs_old = 0x0B000000 / 2
108+ start_lfcs_new = 0x05000000 / 2
114109 start_lfcs = 0
115110 year = 0
116111 if (len (sys .argv )== 4 ):
117112 year = int (sys .argv [3 ])
118113
119114 if (model == "old" ):
120- model_str = b "\x00 \x00 "
115+ model_str = "\x00 \x00 "
121116 if (year == 2011 ):
122117 start_lfcs_old = 0x01000000
123118 elif (year == 2012 ):
@@ -137,7 +132,7 @@ def mii_gpu():
137132 start_lfcs = start_lfcs_old
138133
139134 elif (model == "new" ):
140- model_str = b "\x02 \x00 "
135+ model_str = "\x02 \x00 "
141136 if (year == 2014 ):
142137 start_lfcs_new = 0x00800000
143138 elif (year == 2015 ):
@@ -150,7 +145,7 @@ def mii_gpu():
150145 print ("Year 2014-2017 not entered so beginning at lfcs midpoint " + hex (start_lfcs_new ))
151146 start_lfcs = start_lfcs_new
152147 start_lfcs = endian4 (start_lfcs )
153- command = "bfcl lfcs %08X %s %s %08X" % (start_lfcs , hexlify ( model_str ). decode ( 'ascii ' ), hexlify ( final [4 :4 + 8 ]). decode ( 'ascii ' ), endian4 (offset_override ))
148+ command = "bfcl lfcs %08X %s %s %08X" % (start_lfcs , model_str . encode ( 'hex ' ), final [4 :4 + 8 ]. encode ( 'hex ' ), endian4 (offset_override ))
154149 print (command )
155150 os .system (command )
156151
@@ -159,7 +154,7 @@ def generate_part2():
159154 with open ("saves/lfcs.dat" , "rb" ) as f :
160155 buf = f .read ()
161156
162- lfcs_len = len (buf )// 8
157+ lfcs_len = len (buf )/ 8
163158 err_correct = 0
164159
165160 for i in range (lfcs_len ):
@@ -171,7 +166,7 @@ def generate_part2():
171166 with open ("saves/lfcs_new.dat" , "rb" ) as f :
172167 buf = f .read ()
173168
174- lfcs_new_len = len (buf )// 8
169+ lfcs_new_len = len (buf )/ 8
175170
176171 for i in range (lfcs_new_len ):
177172 lfcs_new .append (struct .unpack ("<i" ,buf [i * 8 :i * 8 + 4 ])[0 ])
@@ -181,12 +176,12 @@ def generate_part2():
181176
182177 isNew = False
183178 msed3 = 0
184- noobtest = b "\x00 "* 0x20
179+ noobtest = "\x00 " * 0x20
185180 with open ("movable_part1.sed" , "rb" ) as f :
186181 seed = f .read ()
187182 if (noobtest in seed [0x10 :0x30 ]):
188183 print ("Error: ID0 has been left blank, please add an ID0" )
189- print ("Ex: python %s id0 abcdef0123456789abcdef0123456789 " % (sys .argv [0 ]))
184+ print ("Ex: python %s id0 abcdef012345EXAMPLEdef0123456789 " % (sys .argv [0 ]))
190185 sys .exit (0 )
191186 if (noobtest [:4 ] in seed [:4 ]):
192187 print ("Error: LFCS has been left blank, did you do a complete two-way friend code exchange before dumping friendlist?" )
@@ -195,10 +190,10 @@ def generate_part2():
195190 print ("Error: movable_part1.sed is not 4KB" )
196191 sys .exit (0 )
197192
198- if seed [4 :5 ]== b "\x02 " :
193+ if seed [4 :5 ]== "\x02 " :
199194 print ("New3DS msed" )
200195 isNew = True
201- elif seed [4 :5 ]== b "\x00 " :
196+ elif seed [4 :5 ]== "\x00 " :
202197 print ("Old3DS msed - this can happen on a New3DS" )
203198 isNew = False
204199 else :
@@ -212,51 +207,47 @@ def generate_part2():
212207 msed3 = getMsed3Estimate (bytes2int (seed [0 :4 ]),isNew )
213208
214209 offset = 0x10
215- hash_final = b ""
210+ hash_final = ""
216211 for i in range (64 ):
217212 try :
218- hash = unhexlify ( seed [offset :offset + 0x20 ])
213+ hash = seed [offset :offset + 0x20 ]. decode ( "hex" )
219214 except :
220215 break
221216 hash_single = byteSwap4 (hash [0 :4 ])+ byteSwap4 (hash [4 :8 ])+ byteSwap4 (hash [8 :12 ])+ byteSwap4 (hash [12 :16 ])
222- print ("ID0 hash " + str (i )+ ": " + hexlify ( hash_single ). decode ( 'ascii ' ))
217+ print ("ID0 hash " + str (i )+ ": " + hash_single . encode ( 'hex ' ))
223218 hash_final += hash_single
224219 offset += 0x20
225220
226221 print ("Hash total: " + str (i ))
227222 part2 = seed [0 :12 ]+ int2bytes (msed3 )+ hash_final
228223
229224 pad = 0x1000 - len (part2 )
230- part2 += b "\x00 "* pad
225+ part2 += "\x00 " * pad
231226
232227 with open ("movable_part2.sed" , "wb" ) as f :
233228 f .write (part2 )
234229 print ("movable_part2.sed generation success" )
235230
236231def hash_clusterer ():
237- buf = b ""
232+ buf = ""
238233 hashcount = 0
239234
240- with open ("movable_part1.sed" , "rb" ) as f :
241- file = f .read ()
242- with open ("movable_part1.sed.backup" , "wb" ) as f :
243- f .write (file )
244-
245- trim = 0
246- try :
247- trim = file .index (b"\x00 " * 0x40 )
248- if (trim < 0x10 ):
249- trim = 0x10
250- file = file [:trim ]
251- except :
252- pass
253-
254235 if (len (sys .argv )== 3 ):
255236 dirs = []
256237 dirs .append (sys .argv [2 ])
257238 else :
258239 dirs = glob .glob ("*" )
259-
240+
241+ try :
242+ with open ("movable_part1.sed" , "rb" ) as f :
243+ file = f .read ()
244+ except :
245+ print ("movable_part1.sed not found, generating a new one" )
246+ print ("don't forget to add an lfcs to it!" )
247+ with open ("movable_part1.sed" , "wb" ) as f :
248+ file = "\x00 " * 0x1000
249+ f .write (file )
250+
260251 for i in dirs :
261252 try :
262253 print (i ,end = '' )
@@ -274,16 +265,22 @@ def hash_clusterer():
274265 if (hashcount > 1 ):
275266 print ("Too many ID0 dirs! (%d)\n Move the ones your 3ds isn't using!" % (hashcount ))
276267 sys .exit (0 )
277-
268+
278269 if (hashcount == 1 ):
279270 print ("Hash added!" )
280271 else :
281272 print ("No hashes added!" )
273+ sys .exit (0 )
274+
275+ with open ("movable_part1.sed.backup" , "wb" ) as f :
276+ f .write (file )
277+
278+ file = file [:0x10 ]
282279 pad_len = 0x1000 - len (file + buf )
283- pad = b "\x00 "* pad_len
280+ pad = "\x00 " * pad_len
284281 with open ("movable_part1.sed" , "wb" ) as f :
285282 f .write (file + buf + pad )
286- print ("There are now %d ID0 hashes in your movable_part1.sed!" % ((len (file + buf )// 0x20 )))
283+ print ("There are now %d ID0 hashes in your movable_part1.sed!" % ((len (file + buf )/ 0x20 )))
287284 print ("Done!" )
288285
289286def do_cpu ():
@@ -299,7 +296,7 @@ def do_cpu():
299296 address_begin = 0
300297 address_end = MAX
301298
302- address_space = MAX // number_of_computers
299+ address_space = MAX / number_of_computers
303300
304301 for i in range (number_of_computers ):
305302 if (which_computer_is_this == i ):
@@ -314,7 +311,7 @@ def do_cpu():
314311 print ("" )
315312
316313 process_space = address_end - address_begin
317- process_size = process_space // process_count
314+ process_size = process_space / process_count
318315
319316 for i in range (process_count ):
320317 process_begin = address_begin + (process_size * i )
@@ -329,35 +326,51 @@ def do_cpu():
329326def do_gpu ():
330327 with open ("movable_part2.sed" , "rb" ) as f :
331328 buf = f .read ()
332- keyy = hexlify ( buf [:16 ]). decode ( 'ascii ' )
333- ID0 = hexlify ( buf [16 :32 ]). decode ( 'ascii ' )
329+ keyy = buf [:16 ]. encode ( 'hex ' )
330+ ID0 = buf [16 :32 ]. encode ( 'hex ' )
334331 command = "bfcl msky %s %s %08X" % (keyy ,ID0 , endian4 (offset_override ))
335332 print (command )
336333 os .system (command )
334+
335+ def download (url , dest ):
336+ try :
337+ response = urllib2 .urlopen (url )
338+ html = response .read ()
339+ data = ""
340+ with open (dest , "rb" ) as f :
341+ data = f .read ()
342+ if (data != html ):
343+ with open (dest , "wb" ) as f :
344+ f .write (html )
345+ print ("Updating " + dest + " success!" )
346+ else :
347+ print (dest + " is already up-to-date!" )
348+ except :
349+ print ("Error updating " + dest )
350+
351+ def update_db ():
352+ download ("https://github.com/zoogie/seedminer/blob/master/seedminer/saves/lfcs.dat?raw=true" ,"saves/lfcs.dat" )
353+ download ("https://github.com/zoogie/seedminer/blob/master/seedminer/saves/lfcs_new.dat?raw=true" ,"saves/lfcs_new.dat" )
337354
338355def error_print ():
339356 print ("\n Command line error" )
340357 print ("Usage:" )
341- print ("python %s cpu|gpu|id0|mii old|mii new [# cpu processes] [ID0 hash] [year 3ds built]" % (sys .argv [0 ]))
358+ print ("python %s cpu|gpu|id0|mii old|mii new|update-db [# cpu processes] [ID0 hash] [year 3ds built]" % (sys .argv [0 ]))
342359 print ("Examples:" )
343360 print ("python %s cpu 4" % (sys .argv [0 ]))
344361 print ("python %s gpu" % (sys .argv [0 ]))
345362 print ("python %s id0 abcdef012345EXAMPLEdef0123456789" % (sys .argv [0 ]))
346363 print ("python %s mii new 2017" % (sys .argv [0 ]))
347364 print ("python %s mii old 2011" % (sys .argv [0 ]))
348365 print ("python %s mii old" % (sys .argv [0 ]))
366+ print ("python %s update-db" % (sys .argv [0 ]))
349367#---------------------------------------------------------------------------
350368#command handler
351369#---------------------------------------------------------------------------
352370abspath = os .path .abspath (__file__ )
353371dname = os .path .dirname (abspath )
354372os .chdir (dname )
355373
356- # "SEEDMINER_ALLOW3" is checked to allow Python 3 during testing.
357- # It should be removed when 3 is ready for everyone to use.
358- if (sys .version_info [0 ] != 2 and os .environ .get ('SEEDMINER_ALLOW3' ) != '1' ):
359- print ("For the highest levels of customer safety and satisfaction, please use Python 2" )
360- sys .exit (0 )
361374if (len (sys .argv ) < 2 or len (sys .argv ) > 4 ):
362375 error_print ()
363376 sys .exit (0 )
@@ -379,6 +392,13 @@ def error_print():
379392elif (sys .argv [1 ].lower ()== "mii" ):
380393 print ("MII selected" )
381394 mii_gpu ()
395+ generate_part2 ()
396+ offset_override = 0
397+ do_gpu ()
398+ sys .exit (0 )
399+ elif (sys .argv [1 ].lower ()== "update-db" ):
400+ print ("Update msed_data selected" )
401+ update_db ()
382402 sys .exit (0 )
383403else :
384404 error_print ()
0 commit comments