initial
This commit is contained in:
10
namepicker/.gitignore
vendored
Normal file
10
namepicker/.gitignore
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
# Python-generated files
|
||||
__pycache__/
|
||||
*.py[oc]
|
||||
build/
|
||||
dist/
|
||||
wheels/
|
||||
*.egg-info
|
||||
|
||||
# Virtual environments
|
||||
.venv
|
||||
1
namepicker/.python-version
Normal file
1
namepicker/.python-version
Normal file
@@ -0,0 +1 @@
|
||||
3.13
|
||||
0
namepicker/README.md
Normal file
0
namepicker/README.md
Normal file
91
namepicker/main.py
Normal file
91
namepicker/main.py
Normal file
@@ -0,0 +1,91 @@
|
||||
from bs4 import BeautifulSoup
|
||||
import httpx, lxml # need lxml as bs4 parser
|
||||
from pprint import pp
|
||||
import pandas as pd
|
||||
from typing import Set
|
||||
import random
|
||||
from io import StringIO
|
||||
|
||||
|
||||
def fetch_names_table() -> pd.DataFrame:
|
||||
"""Grab the list of most common names across the last century from the american social security agency SSA
|
||||
and parse it out as a pandas dataframe"""
|
||||
headers = {
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36",
|
||||
"Accept-Language": "en-US,en;q=0.9,de;q=0.8",
|
||||
}
|
||||
page = httpx.get('https://www.ssa.gov/OACT/babynames/decades/century.html', headers=headers)
|
||||
soup = BeautifulSoup(page.content, 'lxml')
|
||||
table = soup.find('table')
|
||||
with StringIO(str(table)) as f:
|
||||
df = pd.read_html(f)[0]
|
||||
return df
|
||||
|
||||
def make_names_set() -> Set[str]:
|
||||
"""extract the male & female names from the SSA table and lowercase them into a single set (to be 100% unique, even if
|
||||
they should already be from the source material)"""
|
||||
my_names = fetch_names_table()
|
||||
return set([ n.lower() for n in [ n for n in my_names['Females']['Name'] ] + [ n for n in my_names['Males']['Name'] ] if ' ' not in n ])
|
||||
|
||||
def get_randomized_names_list() -> list[str]:
|
||||
"""takes the unique (ordered) set of common names and returns a shuffled version as a list to be used for
|
||||
sequentially assigning randomized user names to containers"""
|
||||
names = list(make_names_set())
|
||||
random.shuffle(names)
|
||||
return(names)
|
||||
|
||||
|
||||
|
||||
def sha512_crypt(password: str, salt: bytes = None) -> str:
|
||||
"""
|
||||
Produce a SHA‑512 crypt‑style hash (like ``crypt.crypt(..., METHOD_SHA512)``)
|
||||
using only ``hashlib``.
|
||||
|
||||
The output format matches the traditional ``$6$salt$hash`` string.
|
||||
"""
|
||||
# Generate a 16‑byte salt if none is provided
|
||||
if salt is None:
|
||||
salt = os.urandom(16)
|
||||
|
||||
# Encode password and salt as bytes
|
||||
pwd_bytes = password.encode("utf-8")
|
||||
# ``crypt`` uses a base64 variant; ``base64`` with ``urlsafe_b64encode``
|
||||
# and stripping padding gives the same character set.
|
||||
salt_str = base64.urlsafe_b64encode(salt).rstrip(b"=").decode("ascii")
|
||||
|
||||
# Perform the SHA‑512 hash
|
||||
hasher = hashlib.sha512()
|
||||
hasher.update(pwd_bytes + salt)
|
||||
digest = hasher.digest()
|
||||
|
||||
# Encode the digest in the same base64 variant
|
||||
hash_str = base64.urlsafe_b64encode(digest).rstrip(b"=").decode("ascii")
|
||||
|
||||
# Return the full crypt‑style string
|
||||
return f"$6${salt_str}${hash_str}"
|
||||
|
||||
def create_password(username: str) -> str:
|
||||
"""generate a crypted pw hash for this username"""
|
||||
return sha512_crypt(f'{username}123!')
|
||||
|
||||
def my_password(password) -> str:
|
||||
salt = os.urandom(8)
|
||||
pwd_hash = sha512_crypt.using(salt=salt, rounds=1000).hash(password)
|
||||
return pwd_hash
|
||||
|
||||
if __name__ == "__main__":
|
||||
import hashlib
|
||||
import os
|
||||
import base64
|
||||
import yaml
|
||||
from xkcd_passwords import generate_password
|
||||
from passlib.hash import sha512_crypt
|
||||
from pathlib import Path
|
||||
with Path('../names.yml').open('r') as yaml_file:
|
||||
names = yaml.safe_load(yaml_file)
|
||||
# names = get_randomized_names_list()
|
||||
# name_pw_map = { n: (sha512_crypt(pwd:= generate_password(separator="", capitalize=True).strip())) + ',' + pwd for n in names}
|
||||
name_pw_map = { n: (my_password(pwd:= generate_password(separator="", capitalize=True).strip())) + ',' + pwd for n in names}
|
||||
with Path('names.yml').open('w') as yaml_file:
|
||||
yaml.dump(name_pw_map, yaml_file)
|
||||
pp(name_pw_map, width=200, compact=True)
|
||||
200
namepicker/names.yml
Normal file
200
namepicker/names.yml
Normal file
@@ -0,0 +1,200 @@
|
||||
aaron: $6$rounds=1000$foobar$/AkayIb/twFQqLVp5MnQeJp8p1Pt2sOfWzhq6wTNnqnMsQawo0NYlxDuWnBhFXbT6GDTCrs38JgmyDwqOO6CD.,SharingClarkReflectedMunich
|
||||
abigail: $6$rounds=1000$foobar$UhKfDtIT9UdQ0M93H3z61XSiECAuTZOGgm/s7lFxFSHP57DmRN1zpGpKjS/DgaQgaAHumyJ7V5n9qvUU.6plz0,PraiseBurnerHeavyBalls
|
||||
adam: $6$rounds=1000$foobar$Mzfo9xERe9r7d5uHDxg/RejsM1hgHx2M9GBkwvgrFwgMXrQDZUk22nfRgRNMgKrnEAi2nJSZV6DtOzAMtCu1E1,ElectoralBelgiumPredictedVoted
|
||||
alan: $6$rounds=1000$foobar$AYjIzlSVFZZ2Im9RUl0VfjBvPRoEd/s/wKDscsO060VbL5qde77I6Td7f8WSbziFbXpP0r/z0fjh50cU/oVHq1,CurrenciesMotorcyclesRiversideNeighbors
|
||||
albert: $6$rounds=1000$foobar$.MHQgb9DObm52j1F6waW55weIdatBlX8G0FSHt2fTD0xZESkBK7moLT5owdJ0kX7bRXf8T8OKuWSylbSuQZtU/,AttachmentsThatsOperatorExchanges
|
||||
alexander: $6$rounds=1000$foobar$aucI7SNenyzzV0nAMIRQaJpUPaJxGNzHD2ZmULQcL3O3UF.Qxrjk5TkI4BUzHL/mOXVUp6VHcNCYbYpN51CUI0,ChannelsBatteriesMonitorsButtons
|
||||
alexis: $6$rounds=1000$foobar$0lXeslOv.yiv3rHQ2ROgMjsjasY0S3.IHlrRVnlq5syXkF6GZL4Unmt57zjx3.BXw6NJbaEIkNNgcXKs0FUTU0,WasherObligationsVentureEffective
|
||||
alice: $6$rounds=1000$foobar$HWEGkfh7Xynli0Z9NMsZ8YsMYV5f6nXgW.EY7suTxWihGAFESjBWVAyVLMO.q2nXPDVgzx0P7rlrYCBn9/T0S1,CorrespondingBooleanFighterFever
|
||||
amanda: $6$rounds=1000$foobar$llJk1qXcc.H8Z1NUzZU9rxKBb24aTeYOig5fwN/cEfDGcmJNHshvO4tj2EZK9c9MGbVS/B9GcyM/dVphpZq7O0,AstrologyTransitionBreastPriority
|
||||
amber: $6$rounds=1000$foobar$kzAnfDhoqxTqwWCRyfmQuPv2UuwkzQlefUV32TXCIah4xPWISz3n8w7WG5urbEPk1KNERRR2CJZUOvvuRzGM4/,LendingJapanHazardousTopless
|
||||
amy: $6$rounds=1000$foobar$/F9S4x8y4PqRzjxZ03XV.tS79GMJD51c5GRDp0E/oNXpv29UvToBCjuICMgCReTadpn63jofggHhi0vaOTaDD.,NorthwestPopularityAuthorsBrunei
|
||||
andrea: $6$rounds=1000$foobar$yhnd7hV0N2VrturKbgSLFWRJXl2vSto.iyJAqX4eZUrp42iKgnUpsGlPhKD2jrWoeDU9JVscfjsbg8fL3Znjl/,BondageDigitSwitchedCoordinate
|
||||
andrew: $6$rounds=1000$foobar$hZOg2iXrd1PI/iMIZNppA.3TMuKD0sU4Q5.Uq8HoyaMgPY6Y/u64jxkLdXE.1V6bqsdNVxE3adSejBEwEnCIO/,PromisedFallingConfusionLegitimate
|
||||
angela: $6$rounds=1000$foobar$nKTzEw5gEoG6kM3hprpe4uSwAfv423VshKtgQu5rS7UWvusf1pcVlCGN7/XuesUZgmTarp1XvEOLOcbvni5tJ0,ConsortiumClustersConcentrateAdjusted
|
||||
ann: $6$rounds=1000$foobar$iFmHys2UgeoZF/MkXv3S12zuf.SjGhOmqVQONUel4LFhRi36OoWgPYPgcSWEuYQ2cB9s61G5ZCVR.PWbTKs7X1,PointsVoicesForestSalem
|
||||
anna: $6$rounds=1000$foobar$4ylTQV1a/Igy8IA4x0mFTvEgzawD.xaQAL7YYipulffBeU65aYpY78pYw79gwhte8388CsUBaXylA8j92oyeh1,DeploymentCreekSelectiveMagic
|
||||
anthony: $6$rounds=1000$foobar$zrvdq2Zyb9zlTOhy.S.da1DgC1C5f9DDmj7MyHTcX94u4KPvL68via1u/rEIXhTwLRUVOWNb2cqwn0VQ/wVF2.,EncounterGonnaDefendReflects
|
||||
arthur: $6$rounds=1000$foobar$FJ70cmgrLHvzBnth6LcWpQQO4GdXEeAgioEXaBejMqfQuPbVHlwELY9EPBst8BpUSZ4w0jiX3.gFm003HXZ31/,RhythmDatabasesNuclearShelf
|
||||
ashley: $6$rounds=1000$foobar$/ydqEj0Z3b93BD/3vpOWra6uMgqhUeyU2swWNAG07VqNEK/O3xMB1ox1OVObcOBBDjfKb8zDdJFk7EI8afKsR0,FragranceMissileBlockedCollapse
|
||||
austin: $6$rounds=1000$foobar$TTg.68QCBwGYMwl.SN7uHWtqxvUvlAGjyRdwiQI.bSIWeyURLfpR2CP/bcjj5/zk1Dcl.c0xcz6Y1esNOaXl2/,IncurredDarknessChrisWednesday
|
||||
barbara: $6$rounds=1000$foobar$nHEPpRd7bz6ptGCwe6juScyZVWY8BZ4.ef.G94tZbZ3yTJIuEUJ4dWpdis7A/IAUNaYf.gZPS2uM4TY4Bh2VN0,FossilJungleCentresEspecially
|
||||
benjamin: $6$rounds=1000$foobar$VY2j5Eq/uHagoLu96htQIKmSEYXsbHJYzxUZuzi980ikEzv99BNCBWuVqV0nsUMiJWuEbGg/IO77DXizlkXA70,BriefsSuitedPrivacyEverywhere
|
||||
betty: $6$rounds=1000$foobar$tt04W6hjkM2rMOylOPF7s6LliRia8jbNWF9Yxr7ry/bq9zEyO/DYekD8aJ4OcCmzonfsc15IFTUkaZ4UAjXq50,ScoringSubmittedKennedyOrders
|
||||
beverly: $6$rounds=1000$foobar$pJydQK07eW5rfXN793bGZaYHJa0058BHpau6d5T1OxqgSgK0uACz6AkmbLPWnjZRPllaahwkG5ywkp3dO9BOA.,FilesFarmingWomenDistinguished
|
||||
billy: $6$rounds=1000$foobar$IFmnvlmRScNa/NGVPvuZEh7bLih8bvvO8u0ru6dlckP1pO5yULYY8YqCIZnyiJWWyX0abJnzHlMdcPRWV0pqq1,SubstantialDesignCamcordersEnclosed
|
||||
bobby: $6$rounds=1000$foobar$pBYqaWlWxcaBaYyO6isdxcQE0cBJbaMfQtmn7EvyqL2Je.IzM1HE2TEoRsI2vC45zhQHRW32FVpq9yhWvchOW0,SizesPenaltyPossibilityCauses
|
||||
bradley: $6$rounds=1000$foobar$dJW1ccajrfQHmhy1Mh.n9otKxKBqkBD7MO4o3mmUYU85cg7iRmtUng284vMAdlcb.Z19nSAizk1pymclwWHfN1,BunnyProposeOutreachNeither
|
||||
brandon: $6$rounds=1000$foobar$DP1TWnFX0GVRAJDqQ5EzPiJy/CaKXpm1T/dpMDAnaxuSEOcynLGGS6.RkT.5oIEgUXJqh0HWS.zZnWbLSXVaT.,CatholicTimelineBroadwayFunded
|
||||
brenda: $6$rounds=1000$foobar$Qk6NlaWP.TFeE4fer2yjO61F3ISMSD3rNIWJpfgFnabp488JR5Dg7.IiQ5eZzkXMwEhptCY.CTNCc8rf8dXaT0,HolidayCellularHeightsIndigenous
|
||||
brian: $6$rounds=1000$foobar$bmNJ7KlKRXryyZ7pFQdy7pw7c5BMgbs3XYXLnTKbJ/yau2tthUcYqxhikTluUcV1XvVi4BsBN/PXsPmD8VOpm/,AndrewsEnsuringNeverthelessReproductive
|
||||
brittany: $6$rounds=1000$foobar$r0VbZk8xxrHdc36tWiXIZXZGUTgr/uC0KTfU4zCTlH6UXVPN/kgrqP81hjc1FH3bI10s/OyMY89tjupcX6OIn1,ExportCookiesUpsetScenario
|
||||
bruce: $6$rounds=1000$foobar$5v8o9rIQuDKSitje8b2BoYqbjRLzG3l08e2GuskE.V1l8ASuNkqJwOlDtBuOU1j1CAWvX9BNzhUNsAR9wE.CF.,IraqiVacuumFilterComics
|
||||
bryan: $6$rounds=1000$foobar$vY/tPZoGd.lWlXMrbvjxCl4CQFUlD0KzMYzrPFO1FHUMt8fuNdQFNDppBrfhu3DGpX0EFoNy8OiERKZXPVzOC0,AmericanTwikiDiegoWitch
|
||||
caleb: $6$rounds=1000$foobar$97Lhk3wwiHOVm7uJe2YmhLHApgEHUQyXZJvHnKcWXr2ldMz2AjF2gkwM6ikVorL8H61Xb1ir5emPOhH9RZdz01,MixingImagineAnniversaryRespect
|
||||
carl: $6$rounds=1000$foobar$YtOEVcz9hAFGNKIa2bvFJsLIgAWiWmTaClrgI8s/6q95Dl.F9an1/mb733NhDbrryomoS/pwzWp7OnDYPPzmb/,MileageEquallyAppropriationsMemphis
|
||||
carol: $6$rounds=1000$foobar$eb8iLX1Ddi1N099fCBXkG6RDw3tlPEoqpbmCWKyIxs1UrX9waUtLpUHmkGUVFZeZzAMWBri0idUCaCbgzT6YJ1,CumulativeSecondaryTradesSurgeon
|
||||
carolyn: $6$rounds=1000$foobar$ei6HbC0TrYTaZ4ffdvwGKdF5TPLA.tE.2TQVRmWUkpUvzSWsrAcs4iHxgRejxIY/RvlKWOsx1fYwmb313mmYQ.,PresentsKnifeBlocksParcel
|
||||
catherine: $6$rounds=1000$foobar$vwLeYxyiKuWfzZ3KWWIksBO56tSWddHSQTfMFZV5mlvk97e/j9ucagfoQ9ziix2r58OHsF4YErJYatbG11U.F.,InterviewWristStateCancel
|
||||
charles: $6$rounds=1000$foobar$R3DZja1PktqUJXM8tFHS9uhnvaMplliVO1LxHVrVLpoE7mRUyfAso9hOWCVYjZD50vp45PwCJ24uD8//A4pMQ/,StreamsShippedPlayersEcological
|
||||
charlotte: $6$rounds=1000$foobar$24DuYssFKs8W.D2jDnPPLRM/NQZmrHnMwmh.QcOsdwi1CLusHDwdjlhkk9AI5UxSxQQ7qZsiIeSe/SQ6m6b970,BlinkEvaluationsInterestedFacing
|
||||
cheryl: $6$rounds=1000$foobar$eDyZgB.FTwmECGimV/.MWwqhgmBnscC9NkSFivi8S8K5WmMbQ0pCcZlIzXJ7GA/D6FJ6RVIr5pC/M7XO5GpPB/,PublicityWithoutLendingSharp
|
||||
christian: $6$rounds=1000$foobar$Cvc2LROxHb030sK2rcVSbvCtwF2b.nwqqZT0ur6m/Be2SvLat1gJNmj9007g1Ip9Hw4LSm25QjoU1e6mWUJOc1,AnalystsLikedSpecialsCharming
|
||||
christina: $6$rounds=1000$foobar$20G99E34Rv80qBsKnCcNoMHcSiRpUyp8xLk19E1ng1Qw12BSC8Jzu2s8NaKuf54VTcSr4TnozGfzwTb1EZw2j.,MinuteTerminalFocalDemonstration
|
||||
christine: $6$rounds=1000$foobar$ewh1LAFzNOGJH53rM567un1peZZIIt2VmTy7dCcyCbFd1m6qHY7.SMXuSgUyzme2K6qI3Kgh0lnaDwsnp3jkG.,IncludingTerrorConditionalVictims
|
||||
christopher: $6$rounds=1000$foobar$4vlg5pzHuTHc1r/eT6uGyz9WsslBY9fpzqBvRlDLoCCS0Sjpu7cesWphDIQUaMfQH7.zFpwlJWWf/s7OH6K230,AccessoryOriginalBouquetGonna
|
||||
cynthia: $6$rounds=1000$foobar$ioV1Gzp7ndTfz5/0Casfc9zAqw8mtn2khBcww/SWJWMaKIWR7s1FS8GGbxjpAL/8oL3aHISz4X9wV4H8AL48I.,EducationalDisplayedApartmentMoney
|
||||
daniel: $6$rounds=1000$foobar$z0fARmuDlfkd9eDWED3xV.Jjmf/mgzsvNwVPUqiliqfTOQheBkisyvwmJ1llUkN2UFujwoNo.498iocoX1ZQj.,PasswordStolenActualCalled
|
||||
danielle: $6$rounds=1000$foobar$Ib/LynVECJDXAW9A.KrCJ9gyafBHJtXBbrZFHm9BKp4W9p7j.B0KaV7ot5ax217ryUEmNaQcoNIhe01Uy2Ko20,JoinedMotivatedRequestsInformal
|
||||
david: $6$rounds=1000$foobar$VJ9VObrcYD0vkuNOB7cpVCsVm/w.ojaB6W/ZAq1bIGa6HLsrhPLjC3BKCxWNOQ1rKabLEJvBO6wzfmhXPExxn.,EitherRetailPowersProducers
|
||||
deborah: $6$rounds=1000$foobar$HsJxBydJgCzJtNzXJ3IJxlo8WpHQNP73YoW7QqXLYhfCtWrmg.rXBGx.HykZoagyHDhLqnzGVe9j6P0y9WRD11,DesireBeatsMostlyToyota
|
||||
debra: $6$rounds=1000$foobar$S9dwuvus7aWDfW/XF.98nfep5WT1kBI5WRtc.zf7qHQjeZif1l9Sf9bN/4gCYNoFKKlJNP8AJb3bEddZuNFsi1,UsefulTelecomDozensMedicare
|
||||
denise: $6$rounds=1000$foobar$.QVTcRGBfTq5DxVl100xisE4dnospPkV5Sl7FRB2ZrDA8IIwF//wvcpm8Tmi0iCso7yHD1sT/KjPprwrtjUZB1,OscarDeliversStationeryDriver
|
||||
dennis: $6$rounds=1000$foobar$N0I4cm.LGZ89NP/YclZazsTbsjQ92AGIE6tRS8JRLXPMcM.0d4sHVktyjVoqgSfovk0rinEqOe1rH8wfF/cii.,DiscoveryActivityLifestyleFurnishings
|
||||
diana: $6$rounds=1000$foobar$hBc04w5TLX7WT9dpOLDgKNNDYJ3AW79jFG/ANvF3r6yyWVThixaNvnK/n87k2mNpjFlu8qi8kz6xbP60pKkc70,KinaseProperStoppingTries
|
||||
diane: $6$rounds=1000$foobar$2Xn7plTfRFqqKzlx59Xmqp0BGSPJF3E4582QJVpHXt7T9Q0cMRAXlkQa7fSnPOfSnW08eiEdbsYjXrQg7EXSU/,SignedPocketFluidOther
|
||||
donald: $6$rounds=1000$foobar$86dh/jaWHjTfaqzth.8pI3VzbtQCslpmwb.s2hj.vMJ3.sHWpVv6lXY2aHiFIEQ3AogXiDsuGYWjnZofd8BVg.,DecemberVanillaFunctionContracting
|
||||
donna: $6$rounds=1000$foobar$eIJrg4IwLlxdQqH0Qz5W3biJfb6mX1MPX1FsBWSh8Iu8CE3s6/NahnWuhLUt494wl9m0ApCLcToRot4jfMD7d1,UrbanPreviewJelsoftThree
|
||||
dorothy: $6$rounds=1000$foobar$9uk23Aw2BtwxkeHTXyWJhKroz5juIJcy3sehIzKY.Cr/k7FsMkEGRwyGjPcTq/PeqcoZP4x7yEvlXxknbqMD21,PracticesYahooThoughtsTreating
|
||||
douglas: $6$rounds=1000$foobar$Rci6WVofcz6ccVdqOjOb0dhPrDueBJGM9VsDIU4kXyNu0ZmE6aYN9CFv6TWZpwveKR.6cRcJBNsSN5YbbOzCJ/,TrademarkConfidentialDefendExamining
|
||||
dylan: $6$rounds=1000$foobar$ydtHRpF33b1yS8xREXQ9d0br2eAbDIzi07Cc0SSJczL9cnD1wgx4XS881ZRgZ.oLaAyWLIgiK1QxJYLAjeVhL1,ReducedVistaOrangeThrows
|
||||
edward: $6$rounds=1000$foobar$c30Qkpejpj13HuykbeCvJkJGzMkUwutiVL2AQlXI0x1rm29De8ZrMSa9mMxVmohp4jsvGKmBkvtfwlVv4YTfv.,FreebsdCelebsPraiseIncident
|
||||
elijah: $6$rounds=1000$foobar$QDXDDS0CVwtI4I7VSAqn68Mm1y6rcekH5uqtKALW65BymCctN.kKNYYqxRKTz8wwXZ/bjQldCsbjaoMoBa30E.,ReviewedHerselfExcitementDisplays
|
||||
elizabeth: $6$rounds=1000$foobar$/9WY5moeRZUFWsHpLmqBxYJ26FHpLInapJyf9RncSZS1AzAL92QUYymIKJxp.6v5Bhk60SkR4d4yNQ3vN4Qql.,ImportSupervisorControversyKnows
|
||||
emily: $6$rounds=1000$foobar$1TUj4iPqJDALiGfZhuXAh9QEUrh3blO1Ea0JSO2Do1QDPBesgr4MoR0EHq/D58diAlcatsKu4f5SR6knOsXYY/,TreasureUsingEmployeesCollecting
|
||||
emma: $6$rounds=1000$foobar$P7O7Ewa0ALQl7lPZ4WJHu3cbfC6NpewkabJ5LT2199hsyPkYtX.vnFNmb98IFNWh5GH.X9zLKnRu9PEZ5NBDa/,ShallHungryRecruitmentProjectors
|
||||
eric: $6$rounds=1000$foobar$zJCfoM1tb55oLoRydZPZ04lmJuI63yKeucl3.XuCwLBHxK/eff8l8eitdcZg.jMYweRv/ZtJG6aONmr9xUlvG1,LightweightMarkedUniversalUruguay
|
||||
ethan: $6$rounds=1000$foobar$4.1AxIXjXiE0EM.hXQDDGbXsB0xXj6N99YRCZ323bWeC9RAImM71ymOlETzrpfruiepzN9TvIMzFklYEvTHa7/,IndicatedDomainsLeatherSisters
|
||||
evelyn: $6$rounds=1000$foobar$quFgEwXnpBrYa5T8sjonjloWtcG1phHs/3V34dS4QmhcxEmkyw1RTuLv.rBRob1ORGHsKfpMDJuqMOKuFRmDl1,DollsPricesRangersProbably
|
||||
frances: $6$rounds=1000$foobar$ybdXl6wAyetHGqvS5BUBRvQCdly5kFDQiO/jgLtxWWeezYJtttlnAjDhRr7qMSDRFTkgCgnpJ8EV4CD366Akd.,SatinBeneathDecorEddie
|
||||
frank: $6$rounds=1000$foobar$m4q47tMc2cw3yBbo5xu3PVaKf.cLHBb8XFHp8OavKCtfvl.mhs4SoO4kdVO1X3Q8OA/LDbo5/42IqDBIGWaxU1,VolvoIntegrityWivesChocolate
|
||||
gabriel: $6$rounds=1000$foobar$sX5noayEPiYZCtJySyUj5ClMY2cINHTD3iQ/CRtuL/LvhlZavpalu0wRmHsYD3J4QYCllEi1qPj/LYeTffKML0,ModeratorAnniversaryPartnerOttawa
|
||||
gary: $6$rounds=1000$foobar$DeUvPns4c2gsch0El3Op08FUn6YL7gOy53PyWyI7iaHxNJR1jxVj1R5IqYYcrAhvW4m17B/ToLImuQ9MfxODQ0,CumshotsOldestSignatureStudent
|
||||
george: $6$rounds=1000$foobar$4PNQdUA1NPu0sD9SHw2y/aUKe1q8TSJl6GjdcGIRzOUdmNa93B1hiZ5D4S/TCa7pSkwdzwPIDuai6xP3KT2050,DifferentOxygenExhibitionsAspects
|
||||
gerald: $6$rounds=1000$foobar$l1gcMCRbLRy.YnCLmlLxH1DenjVAoylvgvNbj4fFVLt.9Di7iqnbZxP0EvPK4IQBRt.HlsRYRqMtoxeKx4w4V1,ColleaguesHomelessAndreasStylus
|
||||
gloria: $6$rounds=1000$foobar$dCVFMRHzY4WLp4W8kGXKjwBW2Pw5Ppj.qZc97MOPgtYQA7I02q9OAkhd3vqYD6e3Hjw4be5ho4QEAny3d8qX/.,PassageOccurredDeathMixture
|
||||
grace: $6$rounds=1000$foobar$wjZuT.44uUm82sAuKyOn09DU3zUaCcqUCwQpW3aPOF.hSh8dhVwMci9T8Xu2z8uQ37os5xhBW8bJRDH/aqRaP0,LendingInsightCommonlySynthesis
|
||||
gregory: $6$rounds=1000$foobar$bSeSPWH58KDRuW89Qy2.GJ58Ehb/qiP34wUB64nAu2/ephF3uAuedyDj1Xzf.9LX5gZWyLq/snwjDR4yOZ3zw1,CraftsFeedbackReplicationAdvise
|
||||
hannah: $6$rounds=1000$foobar$26HVQutL6BEPPoiX5KVEt/e3yKa3NE.4grd69xXGprzfqrv32cib9VnrcLDp8Sl.oqG0YrvXkoOzB0sb4c8W90,NaturallyKatrinaHardwoodPurchase
|
||||
harold: $6$rounds=1000$foobar$VJmWFmUdpvyZCG3wC3mU3r.SZt2lpHD.RM96zj7llllPk15x6OmLWKQveBlKfAVdTZd1RQaSCG9KQndR0dLny0,GeorgiaEnableMultipleDevelopment
|
||||
heather: $6$rounds=1000$foobar$RXMqG/foeXyS/QFjPPkGafhd9Ndg4THpvzUZi0t1JO.mJiSHpJhokxrcqBvxXK5Y1ypB0arHRMrcrV0KqnQKi/,ReplicationFemalesWisconsinStranger
|
||||
helen: $6$rounds=1000$foobar$wcE2OOgqXvw8QrN/9Oc75kuGPYaVcpiUnPgzNq7/IPEa95XIKQnOvAT0kWBfETmGbIh6c1KzJrUCFhvhMvMh./,ExpandIllnessNortonCommunicate
|
||||
henry: $6$rounds=1000$foobar$ZXHBdq1jLKVN3dLvIKhs15czMX7.6aw2Tmh6NJbgRdWyR7H2.NWEzzBQ4pW.qr559FqNRMtgJxkG5oYi6kp4E1,SupervisorBoardsSpeechesTrader
|
||||
isaac: $6$rounds=1000$foobar$/yPFmCYOayJ1bue0/MdOMTrALkTupJxfcoXIq3GgP0C6i6o1NH95YfS0apzbc4N/z9O7kAzmz09xA4Oit/5xM/,SolarisThehunAcuteEmotions
|
||||
isabella: $6$rounds=1000$foobar$kxPylvgvk/cH87h.ETTlgkhKN/p7uP7PqgQhXHNerN/8N2NbnIIAI3Fiw26clGIs59.j5Y8ZYfJQJxm0nfJs8.,MatchedWelcomeMissileBoutique
|
||||
jack: $6$rounds=1000$foobar$vmPMFMf9GgGpr1C9sP5DQeIDrfG0yeLXLCydlbWAKsiq1jWTME0GRV1XBJnmPOQ9y/hjpIAcEimRQxrJYjwmx/,DefeatSuicideEnvironmentsHistory
|
||||
jacob: $6$rounds=1000$foobar$cywGcMOwPH4BIvX4AzT6WSftQZ7elobKoKehnw1LL2/WFbSMCmWAu6SbJ5tgEms2.DK9CvUgsAI0jEiMG1usd.,DependingPhysicallyCrosswordRetired
|
||||
jacqueline: $6$rounds=1000$foobar$/A/jBcXA4yhOR0.Hby7fhw1gtNzt57bP7M7O9Cu/cgKFyjwhxlk1Cpv/qsy2oa2CqVUKOJplptLPrB.cSWI6O1,TelephoneAndaleCalgaryExercise
|
||||
james: $6$rounds=1000$foobar$vN6xnsOzBWJzNCrY2m3uSBH28D4vQlgrO5RWr1ky/OJBe/YpO0vF.e0UfbirOe0JVXnfxdgX.7zL.bumnFiH80,NewsletterBrokerGlassesGreetings
|
||||
janet: $6$rounds=1000$foobar$AqIvk0am6orIyhN9A55947kTYlolJY3/JxScrP2EdtV7qXsQ8Rq//nRhjzLCPirFUTJUOfF1RiXwKVtIVzwyC1,CommitteesExercisesDisclaimerSaturn
|
||||
janice: $6$rounds=1000$foobar$jv3HQehrn6lHebt2mWbt2b0AEz2bQ58nx1Xo4GA5XgEAqrEALOxS.1xdNb2Xn6LHNxc3hsCFm0bAawC/WRbtF0,SquirtingDocumentationConferencingPoints
|
||||
jason: $6$rounds=1000$foobar$Y8/5Aageu3O2ro3qtG61Poz/U71/nojYpBudzTT/e2My5tu2UJn2wAVJMNmH4Z49LivF0ChjOlzNAvtxZf6EZ1,StoneAfricanProjectorsFlashers
|
||||
jean: $6$rounds=1000$foobar$98Ff9mHfZLfz/wzobS0ZXJIr5KkDPRRpu7Gcd3fHZwbEnvOKQP6jXXgmCMLPY58dMobfeI8R25JN//kG5qJwd0,KodakAssureInflationPurchases
|
||||
jeffrey: $6$rounds=1000$foobar$zG1O5LJtfewMm5zUmPXctU/4sbgDK57cF.WlgduAmI/LnZ2f/MSHVVnsY5UPZP9uCDJvcXYCbiZjRH5cRTqGv1,ChapelBillingSundayZones
|
||||
jennifer: $6$rounds=1000$foobar$mjO21lHABXhW/hJXmk49jObqt2SDZKIA863YH7c.RB9FVko39yDQCwoyCGpByDUHwhxn1HrcWl27AUweKkmbf0,RadioMobilesQualificationsBanned
|
||||
jeremy: $6$rounds=1000$foobar$6NQcuRoIGSBfcvnB0HlI0GkWXP/hb/0PEgTPp.wPtRMUUaBVb9YR6vPFPjSo1DSO4p9i6rzFX7mreTBfMkB9n/,CarbonSatisfyLengthCharacterized
|
||||
jerry: $6$rounds=1000$foobar$Qa1K4djQMj3tZ9HHhxHditEasDYuWMiK0Ley7EI3beiqLVAKn5KqAEsfPP1eCHhDhetvhDlQYZbEfaH3vogSZ1,SatisfyTextbookCitiesProvide
|
||||
jesse: $6$rounds=1000$foobar$.uIL0f/tfN.MZPOwvx/bFvzvs4L0LBA8VlFgsYS8/2Q8yWbUpcbaYY5FGnlpSTR64mwmFvUvUOB98dI1BlZam/,ElsewhereEnquiriesNorfolkNorfolk
|
||||
jessica: $6$rounds=1000$foobar$kc4Vw/dYvQgIcNjzDBTjDiPyq50x4fXhVq9PFqqybnA9wD.J0rrvgX7bt3RsQ4iShifb1Srzc.XL3MVyKDuDf0,NutritionalCommentaryTraditionsGenerate
|
||||
joan: $6$rounds=1000$foobar$qLpDkNDbt5AKSPcavbKgatkYmn9yt0za8LAlvDIZ6aW1ZpxAAa5AQf7U7lQ3TWVehUqc1qbkmSHT5IwNL1Iii1,LatinoAmbassadorTerroristsChristmas
|
||||
joe: $6$rounds=1000$foobar$Hy2.efxWznqMd06gel2YIxiJwkQdC6feMWmbBF0qjBTtrTvzqdbzQEv.ZsFrMDjMkI4Q0IXqbz/uzoniJDO4E/,MightyGlanceBeginningBasin
|
||||
john: $6$rounds=1000$foobar$CALZbkLjLXZ86E7l7DESmPYcTvnTeS9iW0JsjRECguqVNHEzXrtvNJlleBPKsc/W0.rlqYbDM/xqQp2Hlu4.G0,GraphicKeywordIndicatePeripheral
|
||||
jonathan: $6$rounds=1000$foobar$TnaGpoItP9gQwVV7FhE3Qm1aLF1AakwjolJF6N8JKUZlGqg1X2QHIYqWCdYjMZp0LPi2AtRDUffnHUiuEGhmv0,MountainBasketInsuredApril
|
||||
jordan: $6$rounds=1000$foobar$Jhk95fCwEEqaTRHGr/cT84YHyHHSizbacPNA27XuxkpGYzfokVHY3vFSzTqz2Zxwm70aRwnKtoal0O.uLVTRL1,SpecificsCastleProgrammeMerchant
|
||||
jose: $6$rounds=1000$foobar$ue/l54A4adVXRIqOAmg5eirN88OdyZBDpkGFglEIriHHEnUyJg08RwWUEENBdrUHErM/vRVSwXvrRIQYq.wnm/,BoatingCertificatesAdministrativeRequires
|
||||
joseph: $6$rounds=1000$foobar$LNi3/WbHXDofLtsp7ltFSWtaXaVPqrjRcIeb4MI3.LW1gachiyUToQIJdrI8FRflDCyNGIGjLJzS4FzyDfi/w/,DelightSuckingEntitiesPoison
|
||||
joshua: $6$rounds=1000$foobar$9RnY.un4pDhY1PZ1LjCfuz2dr3KjvakEj3cuyN516kxxOHLfjm/84LlJ.iA8lkJ4TP5jA7dG0b22IxNBqAn6G1,SenseSublimePlatePsychological
|
||||
joyce: $6$rounds=1000$foobar$Gce70wR74OxkLX6E1g2jU.uIRQHfSHYhy/.VHeGJXCVIgLWYq0DseBe4TJJIne3pv08kb7V7MWh9wk3LWZYdR1,GovernancePreventionEnormousCornell
|
||||
juan: $6$rounds=1000$foobar$jWA/ff.2xDNSd1R3ChK.Iwks2TH1G3ih9zYdA35dhpQ7QxoOrXmCEBJYKKiPWYcem73ak/liFx/KgFy.7Aas.1,LocatorPlateAnimationPicks
|
||||
judith: $6$rounds=1000$foobar$JEwcLIBp5qOSWx5yR0nOtTl5AU0/h.SRGaA6ba5ljSpgo76TU7UDWfXCdd.wC1SlJuzzz.fg/UjbkXkoLIfp90,OpinionsClubsSubstantialCooked
|
||||
judy: $6$rounds=1000$foobar$xk8R7yMEtYBFC.9/Z02nTu8LF3W.4bEwWb7FcLmafld73Ond/s58unND0KYiuIU40NpyrRDpTtL2WG1VH6SJt.,BlastUntitledIcelandIncurred
|
||||
julia: $6$rounds=1000$foobar$ZoYUMw//tA0z2U7j.XP9C9KaH4/7/hnklTwL8aXCzdA8VGSuGe1dS/zLhLIn8ggNCElqIvFH5XAFpX8kIOnvn.,TeachAppearsFarmersNoted
|
||||
julie: $6$rounds=1000$foobar$xjjgIe8Y06SAw88XMnkFnutipODmc3n9iioT0HkXdDP3wrvr6c72r0HhCFweAxlCCwK3us16efU04oIcOaUiy1,ActuallyLargeAttackedBeginner
|
||||
justin: $6$rounds=1000$foobar$3KULwSRQA/W2A1cOAUjggSXA7s0vXaT4VXHDlByYz3xr1nnKV746hjzobsuWOjv4gy6IV8bWN7jMGSZgW.tfb/,ExperimentalSurprisingRickySound
|
||||
karen: $6$rounds=1000$foobar$Dhfog2IbO3IjgwQgxloCH/.mh.oDDHwpbugDwvRyphOMf3KRZzMgiY.E7CqIOE9mstz7sGYv.MyxW8yoXtXTg/,ToothSponsoredChildrenRenew
|
||||
katherine: $6$rounds=1000$foobar$2kRV7jpklePwRyM4cD5d7L5GvM1CQMMMW/MBpJg1s6TBSyIrj8QQRbrlPMM8CiUEQxlNUPS4e1YDQzVDPSYG80,CanvasSuddenHypotheticalCompounds
|
||||
kathleen: $6$rounds=1000$foobar$9MM2/glyIQsClTLGYYY.DWZws2q019pZ2SW5gYtfqYraVAoqSFywy8phRv5Vqd5PN/vb2AMk4VyGsVmN2mTiw.,BraceletsExecutionSmileTribe
|
||||
kathryn: $6$rounds=1000$foobar$qgx7SfIZ7CTb5Ti/XXmDG76fsu18UYTl15SGZCgFY1fy/HAfIo2rPXPgpZVYvo906ic87MqfCmPf4ggM3ft8m/,MinimumAlcoholAdditionInnocent
|
||||
kathy: $6$rounds=1000$foobar$SthJO1C4LX44P9npuC8f8/KmYP4mrJjdbetqaTUhl5ogaoWuqAks5bkisrmHogYfAXjPu14MajW3fVYtwMzwP1,RespiratorySyriaChiefResearchers
|
||||
kayla: $6$rounds=1000$foobar$j4lJCouYUhpwwoiEIkkPvGFDFUDTVoaV4tU6YOcX81PZEajddMI4WYJsAdHbsUZK1JVTrHC/ymPFfj2nz26M..,VintageResultCertificatesBaseline
|
||||
keith: $6$rounds=1000$foobar$zaB/Q/mQZ8I4ONeH2PsU3plRU4u9n7ifQwZAA6eBcLqLvwIjAgw2zyGP8vXwHhXa7z86U.40PZR5Dv6QjbI1w/,ElectronicsElsewhereLatitudeCodes
|
||||
kelly: $6$rounds=1000$foobar$WdZWjNR4FRLJOXDlSgVsl6lKeqa4N8C.gmJASZktJUxlc.eDNK.hjE2cky5lpILBHCXxylKU6fsgYDxYtVwef0,BreathingManualPerformerDestroyed
|
||||
kenneth: $6$rounds=1000$foobar$9E9McHIjksSKD8InDAuu6Ko/8ktYt3yf/723X2rtSi8f6kWh7sBB0ajcbtDd9E3KceMSGXjOMyrBwfZWzR1wu0,SkirtHistoricSpellingCoins
|
||||
kevin: $6$rounds=1000$foobar$eFDYRw/SRRCDtS4t.O9uLFbmIMyLs6Vf3gb/GERcC61x/VurkvG/N/7gKqkm0peqrOKUMteuRkO.g3WbcOKFt1,VariedExaminesEncyclopediaCologne
|
||||
kimberly: $6$rounds=1000$foobar$FYsnjOtaknayjCBHfnqOozqflFW9v3Iw9qx.DWcfhPyaQZm8magBw/B4F164Z504kriRqe.07Q2a.kA1vfZZ81,StartingCriticalCelebrationMilitary
|
||||
kyle: $6$rounds=1000$foobar$gqFrdCKNJ6IzRflj2iXHWGXYFcfQVBv/zWDpcpO2v9anZpX8mXP5NGuZfhGLg0k3v5jFHTDCNoCdvhzGliVNj/,ConflictsDairyQuantitiesAccessing
|
||||
larry: $6$rounds=1000$foobar$MmG75IMq0d5rxB5uM1IkohMrGtcix46Hiw3N.rYwl2CkYwrui1ocNDGAbZL5tu5K2AOUGxhxwiA64SKDpsrhC.,PossiblyCourtesyCouplesCurrencies
|
||||
laura: $6$rounds=1000$foobar$CXtGB73yHksduDdZzSbVP0/GGXWBVj.FQLgSQ0xCSRFzPjozbl6Mm8VgvFgOSVmwB99Voj0qJ77WINqITxra21,SoughtContractingOperationalManage
|
||||
lauren: $6$rounds=1000$foobar$Z44g13AGHMKZlt0/UyYYQZLsT0EmKk.ab8UWyw9pFnJ3XLirrbm6mSlJ1fCEiFRPJE.savg7hm29yDw9l7rtP1,StakeInspectionCompetitionExplore
|
||||
lawrence: $6$rounds=1000$foobar$vKzBWziCM/KOesRiVcSg7d7pVPHIGQFqtArDqJUi/z5H34RNesa6yAxVXsBlsGoXXgZ6/jozKtNX7TiWoxjRW0,WeblogsOuterDividendDebian
|
||||
liam: $6$rounds=1000$foobar$baraX1GgmxaCqJ2wgRVNKqrWlMn/5uigEVU2kPAQrrdJyyhOP5vBCTK.TeXcFHG4qZucNxVXzFPCwjOVllLzr.,EcologicalLessonCopyrightedMemphis
|
||||
linda: $6$rounds=1000$foobar$XlTDcXZ6iCEG0.ypfCyyS/MqvJYTyEVwvUQ2A8oh6yI6yRnhRHez.64imB/1Z5ApCJbBT4ko0NBpQajUalQDM/,BackedArabiaComputingBerkeley
|
||||
lisa: $6$rounds=1000$foobar$0ssY8DjbZLmgQy4G9vkqGG38mPkIYkLV.DNpe19.IrDbwwjOU6K5Szy.Rs6OIITzUWaxWLxvp6JVdKLFFwPKM1,ControversialAllocatedRegardsPowers
|
||||
logan: $6$rounds=1000$foobar$mn6wftx2vX2FReMiGqzwohAHm6axyvEUsXbrGE2AM.tAur1nS5JD9rU.1q8XW0bHacb2Le2xMz6c6cUWkHwhH.,PlasticOutputStretchReleases
|
||||
lori: $6$rounds=1000$foobar$1l84xwpehd3FK7VSShgq0S3XB3kGq74IvZuhzGeiDrWLvTvq/AWPAJjRCMHx9umeqGI3n16ka5us928nRGsir/,PresentAnymoreTonightIncidence
|
||||
lucas: $6$rounds=1000$foobar$RllqlAfXnEOr19nRkFV5QOtud/Th2GzK4ReFELbsJkCIndvFS/yVSuqsigR5Oztqdaj28Ilj8WmDPbvvBN7Dc.,ConsequenceAmazingNewcastleWatts
|
||||
luke: $6$rounds=1000$foobar$940LbqROjEznDfumnbdw91a4rfVjliOe4/HJt9UnoldvmVaOvq3I.YNfBMyx8Yttp28DcVZrjmv689QRChTpl/,BallsThesaurusPaperTrustee
|
||||
madison: $6$rounds=1000$foobar$gapX3kpy3HnXpl7wAEWUTz6En3OLsGT4qe1h5OaR99Iyex.X2QIODDSuKQJKzSSAoeVkMznj/AaorYhGc2oSJ.,ViolenceTermsStrongAssign
|
||||
margaret: $6$rounds=1000$foobar$kASM2TTLmWOvrWr1D3eT/M0pRMRKOs4qiQl8pA0tLPQzMPysc.tuel28MwWamXmZ2C7DUoQDRxpc1S1fYFPu4.,ChaptersStartsPlainsFourth
|
||||
maria: $6$rounds=1000$foobar$GpqbwJnwCMJAO6Cixn2FRDwWkduE3Thes85HqkVnEw3sYxQPz3mJkyFhNmT5Qkflcyrv1yjO.XLuqrAJPsu7v1,ResortVariablesBidderPlanners
|
||||
marilyn: $6$rounds=1000$foobar$2n8ew.pOthJrQfoWiydX4t0emqe3UaAiRaKeEbtF1dSJq5mWDvQeEFVk/Gg1xUsBj3jkJgw3USdCeP19z1i9v1,PlateInnovationsYugoslaviaIrish
|
||||
mark: $6$rounds=1000$foobar$LrkszyNP3Akb.fS0xvvTkka7SQDyrEabOtGwqCeF1qdVge8isLwpSVKvl5fl2.9lUWzAw2PJ9IFdA3gJVmjM21,CongressSagemTraceReprints
|
||||
martha: $6$rounds=1000$foobar$DuDTtZLJ061zGRRoPB6jRFbQNl5VxOgx1KmiS2Av7b4NHXrLEw1pWVcnZr6RcqwcT.KG3hxSUdYxgKBinyWQQ/,DependLargerOperatedNewest
|
||||
mary: $6$rounds=1000$foobar$vbDYt4ru7qp8a0ZpP0GTA1YBqcwuSwGyYfYDLD0HzJsoP9kI9JMfb31q5.Q.Ejn9IcGppszcWzXUDfy/WEnh1/,InfectionSuicideFixesHearing
|
||||
mason: $6$rounds=1000$foobar$xtYSU5FvMS2PAQyY7t.BiiwdTeYHpu86c5py.BqDQZQ7UiVBtRKtQkUuLX.Bjvfh93thNcfFXDla6TjwesEmn/,RoyaltyMinimalFourthRecreational
|
||||
matthew: $6$rounds=1000$foobar$ocmZUTtwEntGNV7SW.7ldrxMPQfoNPk7g/mwxT7WrId0um/IFLwQRIXGLcRQumZr7rx02X3zBuLF/z.voxsdh/,SublimePotterConfiguringDanny
|
||||
megan: $6$rounds=1000$foobar$ISvkPiWVMzub9ZBZmrKl8lK/D3Zh.yzwPZREt9cVs.50fUgvcaPV4KAY.CHqBsK5rjq2TDsd/9ubIXKJYdWFT.,ScannedExemptIllustrationsSquirting
|
||||
melissa: $6$rounds=1000$foobar$MKMbVKnBM0d0cQhNYwbRIf0eD3reOKtdC1FCPhG1scFhtA1MubF877BxlnkIUNJHb.Pi7qtfYSLbO0jaZJqxt.,ForecastsChargesRecordFinance
|
||||
michael: $6$rounds=1000$foobar$bc1.xAOvZB1IUahkKBiQEORRSYxtS0odgn78JM2Zdv3Ok5yzTxQaucqhkNhFMK/mK8W.vzxUO.M678BNEcQsI1,AdobeIngredientsGlobeDeclare
|
||||
michelle: $6$rounds=1000$foobar$mENSc1yikBj3ZiXkW1qGoSrvGxyQZqfgUme.1DUWkvxA2ETaxJIDrXVSCEeCutC5YiaQl9wKSsoHliOLPFBww.,TightGeneticsStrokeSmaller
|
||||
nancy: $6$rounds=1000$foobar$mXlNWgxoIB4Ukc1Kv/Y4vCO0ipuV.OhLcLPPHF3FGo7bhgGCdTzzI7xJUFzLrkXGm.9mpclXcAFdxXlY/m4Cu/,FavourEssentiallyMobilesPrecisely
|
||||
natalie: $6$rounds=1000$foobar$A.g4TkLKKjMlebEtIUeiwin/.VHeyYmoV.9LrroULBzJ8q.HkHUJN1FD9HTHWRDfQiQYjIRIn3/V33.wQlrEO1,KennedyFiltersFacialNodes
|
||||
nathan: $6$rounds=1000$foobar$n8MRulpmZ1oQR3mp9ffEFr6EG5NAtsQ2osnrM2NDTZlsGMT9UwJ9V9ry0u8aCAbQOX7V8WkvQDbWPwwBxX05V/,TravelersAggressiveMuslimsAnswers
|
||||
nicholas: $6$rounds=1000$foobar$44hKtISXPPbYjBHMNrrt3L5OP8TPcEEqsmZcpii3qhuy.htpyIvuVEbRXBsKNVOeFcR1uJFY1vXovZljeVvm5.,ParticularPlymouthDivingPittsburgh
|
||||
nicole: $6$rounds=1000$foobar$0KrE6cbQ0QI/RzDLG2jeWp2KshUVSW5k5YwDI2wPB/fCxmnyK8OL4WY0GOWK827Qs06v4vY3e5j8xrdB6e6px1,KeyboardDozenAcceptsJacob
|
||||
noah: $6$rounds=1000$foobar$oB1XvsNDywFHvQ.tI4hHvQfB16u5LqkRjaeU1Z49rpvFQwzWGeYogfFOI/4JXBomwec/RmUX6GAfQl6C9LXjn1,ShortlyHollywoodRouterTrial
|
||||
olivia: $6$rounds=1000$foobar$Os45sGP6GArpMRSnvw5IfqCabbPId8FMCu7Ge4ceQ.CmTo/ph/ul5oapaoLJu.cYBUNadRRzUjYiA/ew4LVWe.,IndustriesCaymanSonicLuther
|
||||
pamela: $6$rounds=1000$foobar$yYLpRFR1lApm55bVO/RvmzPcXnldfk5DQlRZzaf54lmT4Vv.V6thgRlUNsDe.ZEMvCVDDUHeqqhdliJ8afnAA.,ChambersTrucksNotreSatisfy
|
||||
patricia: $6$rounds=1000$foobar$iyvHuvnSS4mf2VC0dxEzE4JKttF7R/akDvBxGtIdJqrzm2i.u5YCcDj.Cob0KS7zhZ5zfHy4jP0UPOnkxtZ6r0,SubmissionsAssociationTransitWhereas
|
||||
patrick: $6$rounds=1000$foobar$TpVIjY43m6WMzy7ZLxGI3Q2O2pF1SOYBUjV7TBezrLKn531V1UE/wRIq93kveoYcdErkjvuGqah0anGfbUC4B0,FundraisingMalawiSecretProzac
|
||||
paul: $6$rounds=1000$foobar$PWChlv..YaJoVRPLNvwwrJmQ6RrGK101q4Vd3i7q9iuHzNRDC5bybTPbis3JcAC006vBfAaRPrydXTGirhKpR.,ThemselvesJapaneseThirtyAdaptor
|
||||
peter: $6$rounds=1000$foobar$B2EuWhsFOssmN2Rzm0LdCrSevaa0Z4JD1Ag7jKk5Cd5p/SjWiay0bPOwR.3hSHmFW5yhPjMviB7hrS3OzEKtX/,AccountAmountSlopeCattle
|
||||
rachel: $6$rounds=1000$foobar$jBzJI0F4zHKGpdrOjaoGKjMj56sBB49uKRZ/9u63hlqo8oczAPa6lfqLGINfgvWrfAHFBDrmiLmq1KPWYG/oP0,ReviewedShadowBeaverKentucky
|
||||
randy: $6$rounds=1000$foobar$ewRjuVFtJYImbZkUIm8co8HB6H1goX1t0J/H2c6AO/I281ws0tK0uYh0Hhc5XxnVX8f5RcvYUmkJ37TR3A5LN0,StephenHandsRentalsConditions
|
||||
raymond: $6$rounds=1000$foobar$LLGUD351Bz0VER9K4YXsH/7jnszzd7m6iqzfAGbuYRiENkBJA0.WZD3sRi2cBDzOsdtl91YtuRo0jWigq/YcX.,RailwayMightHeadquartersDemonstrate
|
||||
rebecca: $6$rounds=1000$foobar$AEaejdY6xmBZgloll46J7zPAWPWhb.Wd27sHRv7hugIvRNrPxM9Fqrsb.ZpClp/dJNWxMnvgugrvP1Lu87gP31,BootsImmigrantsCreativityBiography
|
||||
richard: $6$rounds=1000$foobar$s954H7sB0.PUlMBB/zH80FBlwh6Xs1c26pit3LfWbn83QCfNTs7oTktk.tHgZlh/Oq.KQZn5BzbZgGnoBOdAw.,PresentedStrictlyOperationalUniverse
|
||||
robert: $6$rounds=1000$foobar$qt5L6s3JtPT7igjzh99XEbmojghs2ssmIBFz7MXM2/R7Hn5fcwx0fF2x9ozeQwERuKz202k9yeM83pCL1mCsN/,EditionBraceletNativeRalph
|
||||
roger: $6$rounds=1000$foobar$WvrnIEejdQxGoiL0zH7zaaHFl7WV11O6hJnH6w19RIZ2zbfHjDyHm.kNdfZQK2XeZ0n1ibUd1hEMRANtVJaqI1,GnomePursuantBravePodcasts
|
||||
ronald: $6$rounds=1000$foobar$2gfnmtcLM5ugGbtyiW7B4SC0t9EbXNUI7Dn//Ugumm9E09jV6cyBle.R5dwmlbR3ilnMZ/jnb11xaomnQ84w41,BoliviaMarieDetectedDistinct
|
||||
ruth: $6$rounds=1000$foobar$ZaQg9KvNMKwQXM2WrPMrt6Kpm6frROERXfGt21CZOQe66uUJGjN7qJgNFZcZk0YEXE7Bdi9kdE4QBpgf9xyCn.,DeltaMilesIllustratedPolished
|
||||
ryan: $6$rounds=1000$foobar$pP1vGnX6JTeCb08kpiz.J275pZglzAm79wJUwYrhoKH/BPSBrrgrP80CR4dTuCra5kpevv2tzTraw1DtoF2Le1,KnivesNudistSystemMessage
|
||||
samantha: $6$rounds=1000$foobar$GpPpOtbum46lshxY3pt10GDydFIDEEng5loxGTR37SWhCjJz1P1Nr4NPZbCrcsbrgpTz5RWgHscDatdqXPuk51,PercentBingoEmissionsContinent
|
||||
samuel: $6$rounds=1000$foobar$HYLAgSkvwnrv9MIFiZVqBM0.lF89I1t1F/KpnV7AMMe4I76mDe.aptEUJl0yOvDdrhuIRSWafzPhokPk9yc2e1,CalledPendingHeadingBeverages
|
||||
sandra: $6$rounds=1000$foobar$S8xQR/B2gERfHz02RHPRw4YAnN9X.IhW607/8HHEwOrX7s/vihfyrmE.U4O4pK075HLPNnn52cSgSVPQcapnU1,SamoaAttractionAccommodateSonic
|
||||
sara: $6$rounds=1000$foobar$BCeAnZZmS3Ufk6hW67PeA5P0az4sCKNejp5AcXE8pFCXXyQbtvvRy/Vf45kGP9CTlrbK9v1sFWT4SbARmSjv6/,ProvidingAdvantageEntireLanes
|
||||
sarah: $6$rounds=1000$foobar$YGcqyDl99HMrGB3bJ3qrieDUNFkOfinTcMa.CHqeVF1DySJ0tHxGhZXQ5mgxO5h2MDjBxpa.f3kqEuFe72kjX1,PeterPublicAbstractDescending
|
||||
scott: $6$rounds=1000$foobar$Vrq6NKaL/xOYDrdJjSxfLyN8qYpuTCrolCf1A50RqkFmxBk8PXg.mmVXeTURndLGrwFB9CjTHtdU4T8nkgnUF1,TeacherUpcomingAdvancementMetallic
|
||||
sean: $6$rounds=1000$foobar$6dnZ5CqQD.BlGfzL1YEWuzmFsAR1yCXPYyY5F7PnYNdOg5u9jvYlPBTkBAZOENMIoo3DVsErIXeMRU2WOTt/V.,CarriersSquadArubaConsolidation
|
||||
sharon: $6$rounds=1000$foobar$noogFI7R39yAvo4LETAlLgTTxWgkx5jZ05ygZWmD5HQvQAtdK6/CjxdRXdcl8XPurUDusTS7Xs/QISwehLGQn1,HighwayMagneticParticipationProvisions
|
||||
shirley: $6$rounds=1000$foobar$LE6JSJFh43xH0oWXitF.zaJ/cUv7.zvYacW9j9L11zF7Qv9u1qY6iIMdZGigHsdYimvYG.HLBbY6fUs5tzeGJ1,GlassesMiniatureApproximatelyPermissions
|
||||
sophia: $6$rounds=1000$foobar$FTyhbu8311bYDcUcPxMrj5BDUWOCQuY2e0kcgakSWC6htrXorbizIFhU5dosH8XNAspljEh2IjdfZL9jV.AGW0,FrequentlyAssistsAssignedArbor
|
||||
stephanie: $6$rounds=1000$foobar$YSIqsFh1QwEUQ/PdcQE1Xkt04vjOkqlld7gN5uPQ4iRITfZQ7j50piiAq8hjLOYzgS4UunZRJKFBPw1/DsIXM0,ComplianceFarmingLimitRentals
|
||||
stephen: $6$rounds=1000$foobar$P/SaadViSKuHFZUZgyS/UGKZ71R5duneeGNCXNYLYyjJq2..ogDkORaOFEwGRjNaUBoegTiQdxIXktQBKXm9d0,GamespotConnectorHighwaysCourts
|
||||
steven: $6$rounds=1000$foobar$hKEC5RxQwZbs3SNDxKUILamePPSSvlI9lU4Woe0HUyOwqpXvZw4sCsTtHY/.O.7Thrbh.frYp/.I7nbN4qR8h0,ChoosePleaseEpinionsSalem
|
||||
susan: $6$rounds=1000$foobar$ElmgjhK8HpP.J8HEpCFfY9lKihY00dXbifqX0P2T1vWTtRfdhcg37BDbnU48/8SSq1/If5FzxlTBGRx2uN9DP.,CloudsInstallingUtilityLuxembourg
|
||||
teresa: $6$rounds=1000$foobar$YsR6m5aIzW9WNaQVgZ2OcqAOsr8RIXrAGgjLTxqtcw0tAlE1xU0UkWE4rf5QwUvLGcnLqKwDKGTpcERu4qAZw/,FotosAddressesFlowerInvasion
|
||||
terry: $6$rounds=1000$foobar$N0gquC4y9JnanNZDG1L4p0Q2KHvZnyEw6MfhjtK1QJKtG5a/PW4O67/xFKdaFBC87TdQScsmFWjP0glI8dIuU1,ChangelogRationalMountedSponsorship
|
||||
theresa: $6$rounds=1000$foobar$VAU6fB65ZG2VfgBt9PrMb8DX57qynJU8kUWAX7DQn3jo7UpBYdp99DsjfW0oWG05dY6Ndmd4brTfU4k0x8zvl0,BrutalAppreciatedAucklandPositions
|
||||
thomas: $6$rounds=1000$foobar$.Hk4uVMnVmh4KzkdpZ/z8ToSkdCIYNPTcUVmzA9wr.8u/HGOlGzLSqpLufrSWU3d2IFr/SnjneOSlVfmPuxLO/,WarrantiesDeutschlandRepublicDistances
|
||||
tiffany: $6$rounds=1000$foobar$ITse2sfHeVYSMjG6xY3fyznwPXwFeKZeBjvw1Bg5N4g6G8Fjo7ffktzoIxX3VKKTVK6l3iRr6dksKNuEYjQrV.,ConstraintsAnotherWhetherModules
|
||||
timothy: $6$rounds=1000$foobar$4DSzxNENU17W38nE1ljHyfRLalkATEd0kvMxsR9VIZ5YpDU6ochdwcLMZJn4l6zrILf5rwuMHdFV6u7M.n.q//,OriginalTroopsLevelPsychology
|
||||
tyler: $6$rounds=1000$foobar$axMaCayjttUIaSLyWHuLnhtshqIO0DgZLTsj/4H39TS5h91udUHqpRxieu39bN6o4JpOHhjY0GTnj.W0wONhX0,TamilRolandAccordanceResponse
|
||||
victoria: $6$rounds=1000$foobar$EQRrMnXIsJKgH055Gjh1qQw0Z7ejNF0Z1Y91siXjd.0ii1Ihb54XeSIFGFpDi3F9Ik2QECC/0BbizvzuzGk010,TerraceCompilationCachedBangbus
|
||||
vincent: $6$rounds=1000$foobar$pxZlJYT94LtvdR0KmzvQ113M0mP5fCKhVHUQOFjEQvXaz0.CSZ9LDhDmNQ6fxc5aR/GeQ70VPAF1lu5pMf0V71,ArrestChristianExpansysComposite
|
||||
virginia: $6$rounds=1000$foobar$y64JbpwXDJyVYjZBXEtMIHn.L/Kutzrleqh8OQVIPqjC6u4EavVjo8Vj502HC1mgP5m2vT.JpwdnhzBcGw6C60,TicketMoneyGroundImperial
|
||||
walter: $6$rounds=1000$foobar$YhrbkGUGLCpZ31/IvoOLPmiqCSl21hvtrX2VfJIAfKWVyUrjdZ.OdO4l1F/g2iz3W/Z/kuU/7bxi3rNoEP7G1.,CopperCoastConfusedRecent
|
||||
wayne: $6$rounds=1000$foobar$Fgsekrc29M0xcJoWOXRKSUxWgSDPOZVXzEjF53JviXg2hMcsnyp2.haAwEmyT3PqBBgp79cufCU6d8g2E60mZ0,SignatureWidespreadCrossingBookmark
|
||||
william: $6$rounds=1000$foobar$fnaFDubi8rG7yfiqhKpmtFTLHGR2qy3.oy8hy2S1wAcjQcivs2EbbhaVaUj9XtBybVUJLhGDnjo8m1I11Ct8U0,ObtainedHendersonCentrePayroll
|
||||
willie: $6$rounds=1000$foobar$/Pw0tVuAwAoTszWwOXtQYSRj.7qNFqc2C21yL0V0HNcZCJOQ60q4x.PNCy8TOzSG9rxzrSrb.7Lc4z9bAcP2J0,SchemaWroteConnectivityInfinite
|
||||
zachary: $6$rounds=1000$foobar$HpbILboobvEJg28.j.QWvwxRcEtffycGBKGEHAx1llYWa7kr4KmsBPsVTTxojj0pPe/Mc.zv1jOBFtE2Vbxjx/,PipelinePanelEmeraldIncluded
|
||||
1
namepicker/peg-creator.py
Normal file
1
namepicker/peg-creator.py
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
7
namepicker/pyproject.toml
Normal file
7
namepicker/pyproject.toml
Normal file
@@ -0,0 +1,7 @@
|
||||
[project]
|
||||
name = "namepicker"
|
||||
version = "0.1.0"
|
||||
description = "Add your description here"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.13"
|
||||
dependencies = []
|
||||
122
namepicker/webserver.py
Normal file
122
namepicker/webserver.py
Normal file
@@ -0,0 +1,122 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Simple HTTP server that works on both IPv4 and IPv6.
|
||||
It prints the client address (src) and the local address (dst) for each request.
|
||||
"""
|
||||
|
||||
import logging
|
||||
import socket
|
||||
from http.server import BaseHTTPRequestHandler, HTTPServer
|
||||
from socketserver import TCPServer
|
||||
|
||||
|
||||
## wrangled together by stackoverflow & duck.ai GPT-OSS 120B to add dualstack support
|
||||
class S(BaseHTTPRequestHandler):
|
||||
def _set_response(self):
|
||||
self.send_response(200)
|
||||
self.send_header('Content-type', 'text/html')
|
||||
self.end_headers()
|
||||
|
||||
def do_GET(self):
|
||||
logging.info(
|
||||
"GET request,\nPath: %s\nHeaders:\n%s\n",
|
||||
self.path,
|
||||
self.headers,
|
||||
)
|
||||
self._set_response()
|
||||
self.wfile.write("<body><pre>".encode())
|
||||
|
||||
# echo request info
|
||||
self.wfile.write(
|
||||
f"GET request for {self.path} from {self.headers}\n".encode()
|
||||
)
|
||||
self.wfile.write(
|
||||
f"client (src_ip, src_port) = {self.client_address}\n".encode()
|
||||
)
|
||||
self.wfile.write(
|
||||
f"local (dst_ip, dst_port) = {self.request.getsockname()}\n".encode()
|
||||
)
|
||||
self.wfile.write("</pre></body>".encode())
|
||||
|
||||
def do_POST(self):
|
||||
length = int(self.headers.get('Content-Length', 0))
|
||||
post_data = self.rfile.read(length)
|
||||
|
||||
logging.info(
|
||||
"POST request,\nPath: %s\nHeaders:\n%s\n\nBody:\n%s\n",
|
||||
self.path,
|
||||
self.headers,
|
||||
post_data.decode('utf-8', errors='replace')
|
||||
)
|
||||
self._set_response()
|
||||
self.wfile.write(f"POST request for {self.path}".encode())
|
||||
|
||||
def make_dualstack_server(host: str, port: int, handler):
|
||||
"""
|
||||
Return a TCPServer that listens on both IPv4 and IPv6.
|
||||
The socket is created, configured and bound **once** by us,
|
||||
then handed to TCPServer. We only call `server_activate()`.
|
||||
"""
|
||||
# 1️⃣ IPv6 socket
|
||||
sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
|
||||
|
||||
# 2️⃣ Enable dual‑stack (IPv4‑mapped IPv6) on platforms where the
|
||||
# default is IPv6‑only (macOS, Windows)
|
||||
sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 0)
|
||||
|
||||
# 3️⃣ Reuse address – convenient during development
|
||||
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
|
||||
# 4️⃣ Bind the socket ourselves
|
||||
sock.bind((host, port))
|
||||
|
||||
# 5️⃣ Build the server **without** the automatic bind/activate step
|
||||
server = TCPServer(
|
||||
server_address=None, # not used because we bind manually
|
||||
RequestHandlerClass=handler,
|
||||
bind_and_activate=False,
|
||||
)
|
||||
server.socket = sock # replace the internal socket
|
||||
# server.server_address is optional; we set it for nice repr()
|
||||
server.server_address = (host, port)
|
||||
|
||||
# 6️⃣ Only activate (listen) – do NOT call server_bind() again
|
||||
server.server_activate()
|
||||
return server
|
||||
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# Main entry point
|
||||
# ----------------------------------------------------------------------
|
||||
def run(host: str = "", port: int = 8080):
|
||||
"""
|
||||
Starts the HTTP server.
|
||||
* host = '' → listen on all interfaces (IPv4 & IPv6)
|
||||
* host = '::' → same as '' but explicit IPv6
|
||||
* host = '0.0.0.0' → IPv4 only (still works with dual‑stack socket)
|
||||
"""
|
||||
logging.basicConfig(level=logging.INFO,
|
||||
format='%(asctime)s %(levelname)s %(message)s')
|
||||
httpd = make_dualstack_server(host, port, S)
|
||||
|
||||
logging.info(f"Starting HTTP server on {host or '::'}:{port} (dual‑stack)")
|
||||
try:
|
||||
httpd.serve_forever()
|
||||
except KeyboardInterrupt:
|
||||
logging.info("Keyboard interrupt – shutting down")
|
||||
finally:
|
||||
httpd.server_close()
|
||||
logging.info("Server stopped")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
if len(sys.argv) == 3:
|
||||
# usage: script.py <host> <port>
|
||||
run(host=sys.argv[1], port=int(sys.argv[2]))
|
||||
elif len(sys.argv) == 2:
|
||||
# usage: script.py <port>
|
||||
run(port=int(sys.argv[1]))
|
||||
else:
|
||||
run()
|
||||
182
namepicker/xkcd_passwords.py
Normal file
182
namepicker/xkcd_passwords.py
Normal file
@@ -0,0 +1,182 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
XKCD “correct-horse-battery-staple” password generator.
|
||||
|
||||
Features
|
||||
--------
|
||||
* Uses the official EFF large word list (7776 words, ~12.9 bits/word).
|
||||
* Caches the list in the user's cache directory.
|
||||
* Fully type‑annotated, no external dependencies beyond the standard library.
|
||||
* Optional extra digit / symbol and customizable separator.
|
||||
"""
|
||||
|
||||
import hashlib
|
||||
import os
|
||||
import random
|
||||
import sys
|
||||
import urllib.request
|
||||
from pathlib import Path
|
||||
from typing import List
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# 1️⃣ Load / cache the word list
|
||||
# ----------------------------------------------------------------------
|
||||
WORDLIST_URL = (
|
||||
# "https://www.eff.org/files/2016/07/18/eff_large_wordlist.txt"
|
||||
"https://github.com/first20hours/google-10000-english/raw/refs/heads/master/google-10000-english.txt"
|
||||
)
|
||||
CACHE_DIR = Path(os.getenv("XDG_CACHE_HOME", Path.home() / ".cache")) / "xkcd_passgen"
|
||||
CACHE_DIR.mkdir(parents=True, exist_ok=True)
|
||||
# WORDLIST_PATH = CACHE_DIR / "eff_large_wordlist.txt"
|
||||
WORDLIST_PATH = CACHE_DIR / "google-10000-english.txt"
|
||||
|
||||
|
||||
def _download_wordlist() -> None:
|
||||
"""Download the EFF word list to the cache directory."""
|
||||
print("Downloading word list …", file=sys.stderr)
|
||||
with urllib.request.urlopen(WORDLIST_URL) as resp, open(
|
||||
WORDLIST_PATH, "wb"
|
||||
) as out:
|
||||
out.write(resp.read())
|
||||
|
||||
|
||||
def _load_wordlist() -> List[str]:
|
||||
"""Return the list of words (one per line, stripped)."""
|
||||
if not WORDLIST_PATH.is_file():
|
||||
_download_wordlist()
|
||||
words = []
|
||||
with open(WORDLIST_PATH, "r", encoding="utf-8") as f:
|
||||
for line in f:
|
||||
# The file format is: 12345 word
|
||||
line = line.strip()
|
||||
if " " in line:
|
||||
parts = line.strip().split()
|
||||
if len(parts) == 2:
|
||||
words.append(parts[1])
|
||||
else:
|
||||
if len(line) > 4:
|
||||
words.append(line)
|
||||
if not words:
|
||||
raise RuntimeError("Failed to load any words from the word list.")
|
||||
return words
|
||||
|
||||
|
||||
# Load once at import time – cheap after the first run
|
||||
WORDLIST = _load_wordlist()
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# 2️⃣ Core password generator
|
||||
# ----------------------------------------------------------------------
|
||||
def generate_password(
|
||||
num_words: int = 4,
|
||||
separator: str = " ",
|
||||
capitalize: bool = False,
|
||||
add_digit: bool = False,
|
||||
add_symbol: bool = False,
|
||||
rng: random.Random | None = None,
|
||||
) -> str:
|
||||
"""
|
||||
Return a password consisting of *num_words* random words.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
num_words:
|
||||
Number of words to concatenate (default 4 → ~52 bits of entropy).
|
||||
separator:
|
||||
String placed between words (default space). Use ``''`` for a
|
||||
“passphrase” without spaces.
|
||||
capitalize:
|
||||
Capitalise the first word (adds ~1 bit of entropy).
|
||||
add_digit:
|
||||
Append a random decimal digit (adds ~3.3 bits).
|
||||
add_symbol:
|
||||
Append a random symbol from ``!@#$%^&*()-_=+[]{};:,.?`` (adds ~5 bits).
|
||||
|
||||
Returns
|
||||
-------
|
||||
str
|
||||
The generated password.
|
||||
"""
|
||||
rng = rng or random.SystemRandom() # cryptographically strong RNG
|
||||
|
||||
chosen = [rng.choice(WORDLIST) for _ in range(num_words)]
|
||||
|
||||
if capitalize:
|
||||
chosen = [c.capitalize() for c in chosen]
|
||||
# chosen[0] = chosen[0].capitalize()
|
||||
|
||||
password = separator.join(chosen)
|
||||
|
||||
if add_digit:
|
||||
password += str(rng.randint(0, 9))
|
||||
|
||||
if add_symbol:
|
||||
symbols = "!@#$%^&*()-_=+[]{};:,.?"
|
||||
password += rng.choice(symbols)
|
||||
|
||||
return password
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# 3️⃣ Helper to compute entropy (optional but nice to have)
|
||||
# ----------------------------------------------------------------------
|
||||
def password_entropy(num_words: int, add_digit: bool, add_symbol: bool) -> float:
|
||||
"""
|
||||
Approximate entropy in bits for the given configuration.
|
||||
|
||||
The EFF list has 7776 words → log₂(7776) ≈ 12.9 bits per word.
|
||||
"""
|
||||
bits_per_word = 12.9
|
||||
entropy = num_words * bits_per_word
|
||||
if add_digit:
|
||||
entropy += 3.32 # log₂(10)
|
||||
if add_symbol:
|
||||
entropy += 5.0 # log₂(≈32 symbols)
|
||||
return entropy
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# 4️⃣ Command‑line interface (optional)
|
||||
# ----------------------------------------------------------------------
|
||||
def _cli() -> None:
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Generate XKCD-style passphrases."
|
||||
)
|
||||
parser.add_argument(
|
||||
"-n", "--num-words", type=int, default=4,
|
||||
help="Number of words (default: 4)."
|
||||
)
|
||||
parser.add_argument(
|
||||
"-s", "--separator", default=" ",
|
||||
help="String placed between words (default: space)."
|
||||
)
|
||||
parser.add_argument(
|
||||
"-c", "--capitalize", action="store_true",
|
||||
help="Capitalize the first word."
|
||||
)
|
||||
parser.add_argument(
|
||||
"-d", "--digit", action="store_true",
|
||||
help="Append a random digit."
|
||||
)
|
||||
parser.add_argument(
|
||||
"-S", "--symbol", action="store_true",
|
||||
help="Append a random symbol."
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
pwd = generate_password(
|
||||
num_words=args.num_words,
|
||||
separator=args.separator,
|
||||
capitalize=args.capitalize,
|
||||
add_digit=args.digit,
|
||||
add_symbol=args.symbol,
|
||||
)
|
||||
print(pwd)
|
||||
# print(f"≈ {password_entropy(args.num_words, args.digit, args.symbol):.1f} bits of entropy")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
_cli()
|
||||
Reference in New Issue
Block a user