Skip to content

Instantly share code, notes, and snippets.

@ompugao
Last active October 10, 2022 06:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ompugao/e62d14098b2ba567c0b39e339faded4c to your computer and use it in GitHub Desktop.
Save ompugao/e62d14098b2ba567c0b39e339faded4c to your computer and use it in GitHub Desktop.
password duplicates merger for conversion of passwords from google to bitwarden

Password Duplicates Merger

Usage

# export passwords from google
python3 convert_googlepasswords_to_bitwarden.py ./Google\ Passwords.csv ./bitwarden.csv
# import bitwarden.csv via csv(bitwarden)
#!/usr/bin/env python3
import csv
import contextlib
import urllib3
import ipaddress
import pprint
@contextlib.contextmanager
def csv_writer_context(filename='bitwarden.csv'):
header = 'folder,favorite,type,name,notes,fields,login_uri,login_username,login_password,login_totp'.split(',')
with open(filename, 'w') as f:
csv_writer = csv.writer(f)
csv_writer.writerow(header)
yield csv_writer
def main(googlecsvfile = './Google Passwords.csv', outputcsvfile):
uniquepasswords = []
passwords = dict()
mergedpasswords = dict()
with csv_writer_context(outputcsvfile) as writer:
with open(googlecsvfile, 'r') as f:
csv_reader = csv.reader(f)
header = None
for irow, row in enumerate(csv_reader):
if irow == 0:
header = row
continue
name, url, username, password = row
parsedurl = urllib3.util.parse_url(url)
domain = '.'.join(parsedurl.host.split('.')[-2:])
if domain == 'ac.jp' or domain == 'co.jp' or domain == 'ne.jp' or domain == 'slack.com':
domain = '.'.join(parsedurl.host.split('.')[-3:])
isiphost = True
try:
ipaddress.ip_address(parsedurl.host)
except ValueError as e:
isiphost = False
if parsedurl.scheme in ['http', 'https'] and not isiphost:
if not domain in passwords.keys():
passwords[domain] = dict()
if not username in passwords[domain].keys():
passwords[domain][username] = dict()
if not password in passwords[domain][username].keys():
passwords[domain][username][password] = []
passwords[domain][username][password].append(
dict(name=name, url=url,
username=username, password=password))
elif isiphost:
uniquepasswords.append(
dict(name=name, url=url,
username=username, password=password))
else:
uniquepasswords.append(
dict(name=name, url=url,
username=username, password=password))
for p in uniquepasswords:
# 'folder,favorite,type,name,notes,fields,login_uri,login_username,login_password,login_totp'.split(',')
name = p['name']
url = p['url']
password = p['password']
username = p['username']
writer.writerow(['', '', 'login', name, '', '', url, username, password, ''])
for domain, v in passwords.items():
for username, d in v.items():
urls = []
name = None
for password, vinfo in d.items():
for iinfo, info in enumerate(vinfo):
if iinfo == 0:
name = info['name']
urls.append(info['url'])
writer.writerow(['', '', 'login', name, '', '', ','.join(urls), username, password, ''])
# for k in passwords:
# if len(passwords[k]) > 1:
# for user in passwords[k]:
# if len(passwords[k][user]) > 1:
# for password in passwords[k][user]:
# print(k, user, password)
# pprint.pprint(passwords[k][user][password])
# input()
if __name__ == '__main__':
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--googlepasswordscsv', type=str)
parser.add_argument('--outputfilecsv', type=str)
args = parser.parse_args()
main(args.googlepasswordscsv, args.outputcsvfile)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment