简体   繁体   中英

python iterating through and writing to a file

I need to write a function that opens two files and if a certain comparison is true write the result to a third file:

def crack_pass_file(pass_filename,words_filename,out_filename):
    f1=open(pass_filename)
    f2=open(words_filename)
    f3=open(out_filename,'w')
    for line1 in f1:
        x=make_dictionary(line1.split(":"))
        password=x["password"]
        name=x["account"]
        for line2 in f2:
            if (check_pass(line2.strip(),password)==True):
                f3.write(name + "="+line2.strip())

File f1 is a file containing:

root:VgzdTLne0kfs6:0:0:Corema Latterll:/home/root:/bin/bash
checani:IqAFDoIjL2cDs:1:1:Pengpu Checani:/home/checani:/bin/bash
rkrakow:DLD3nJmCvt3pY:2:2:Rodentia Krakow:/home/rkrakow:/bin/bash
forkland:oWMVyy1FTdNL6:3:3:Forkland Maskins:/home/forkland:/bin/bash
obongo:O44lPEloqk5tY:4:4:Obongo Obwalden:/home/obongo:/bin/bash
pglenda:xboW5dHcsqvSQ:5:5:Pahsien Glenda:/home/pglenda:/bin/bash
madel:qEHvJXMkTSAZA:6:6:Madel Aporosa:/home/madel:/bin/bash
ssauks:Q3Kz1z7eAiwjg:7:7:Schober Sauks:/home/ssauks:/bin/bash
slajoie:wWTHgoE8SC8W6:8:8:Scheiner Lajoie:/home/slajoie:/bin/bash
tieton:RWORYLxRSSzMU:9:9:Lerwa Tieton:/home/tieton:/bin/bash

where each line has a user, a password, and a bunch of other things. For line 1 root is the user and VgzdTLne0kfs6 is the encrypted password. Same format is used for every other line. What I need to do is take the encrypted password and see if calling crypt on a password in the other file, f2, which contains a giant list of words in alphabetical order like:

embordering
emborders
emboscata
embosk
embosked
embosking

will make that password into the encrypted password. I already have the function that does that and it works:

def check_pass(plain,enc):
    s = enc[0:2]
    x = crypt.crypt(plain, s)
    if x==enc: return True
    else: return False

also here is the makedictionary function that I use to make a dictionary out of every line of file 1, also works Ive tested it:

def make_dictionary(s):
    d={}
    d["account"]=s[0]
    d["shell"]=s[6]
    d["UID"]=int(s[2])
    d["GID"]=int(s[3])
    d["GECOS"]=s[4]
    d["directory"]=s[5]
    d["password"]=s[1]
    return d

when I test this it writes: root=stroam to the output file, which is the decrypted password for the first user but doesnt write any of the rest. This should be the result:

root=stroam
checani=asarta
rkrakow=sinklike
obongo=yawnful
madel=aviatic
tieton=dagesh
pglenda=sngissa
forkland=relliarb
slajoie=mu2j1k
ssauks=EGaFeIHC

I found all these words(yawnful, aviatic, etc ) in the words file but for some reason they are not being matched. Ive also tried doing like: check_pass("asarta","IqAFDoIjL2cDs") and some others and they all return true so Im confused why more of them arent printed out to my output file.

You want to evaluate every line in f1 against every line in f2 . But you consume every line in f2 on the first iteration through f1 . On the second iteration, f2 is empty and you won't enter the body of this loop.

for line1 in f1:
# ...
    for line2 in f2:

Instead, outside of your for line in f1 loop, generate a list of the lines in f2 (and optionally f1) like so:

f2_lines = [line2 for line2 in f2]
...
for line1 in f1:

Now you can use

for line2 in f2_lines:

in the body of your f1 loop.

The first time you iterate f2 , you exhaust the iterator, and all future iterations of f2 are loops that don't execute at all. Either load all the lines of f2 into a list so it can be iterated multiple times, or call f2.seek(0) after exhausting it to reset the file pointer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM