انتخاب کلمه عبور مخفف مناسب

شاید شما هم جزو کسانی باشید که علاقه دارید مخفف اسمتان را برای کلمه عبورهایتان انتخاب کنید. مثلا arz برای alireza. اما چرا lrz یا rez را برای مخفف alireza اتخاب نکنیم؟ اصلا ما چطور یک مخفف را انتخاب می کنیم؟
اولین معیار قطعا تعداد حروف مخفف است. اینکه می خواهیم مخفف ما چند حرف داشته باشد.
معیار بعدی احتمالا این است که مخفف ما به سرعت عبارت اصلی را به ذهن متبادر کند و کمترین ابهام را در بر داشته باشد. مثلا اگر مخففی را moh انتخاب کنیم، ابهامی وجود دارد که عبارت اصلی mohsen بوده یا mohammad !
اینکه توالی حروف در مخفف همان توالی حروف در عبارت اصلی باشد هم مهم است. مثلا مطمئنا علاقه ای نداریم مخفف کلمه alireza، چیزی شبیه lzr باشد؛ چون در کلمه اصلی z قبل از r نیست.
با این قوائد، چطور می توانیم یک کلمه عبور برای خود انتخاب کنیم؟


کد زیر به زبان پایتون است و این کار را برای شما انجام می دهد. فقط چند نکته مهم وجود دارد:
1- لیستی از نام ها: برای محاسبه اینکه چند اسم دیگر ممکن است همین مخفف را داشته باشند لازم است لیستی از نام ها داشته باشیم.
پیدا کردن اینچنین لیستی کار سختی نیست ولی اینکه شامل اسامی از ملیت های مختلف باشد کار بیشتری می برد. من یکی از لیست های کوچک که شامل اسمهای ملیت های مختلف است را انتخاب کردم. لینک دانلود در پایان نوشته آمده است.

2- معیار پیشنهاد: مخفف پیشنهادی بر اساس سه معیاری که پیش از این گفته شد انتخاب می شود: اول توالی حروف یکسان با توالی حروف کلمه اصلی؛ دوم تعداد حروف مخفف توسط کاربر انتخاب می شود. سوم مخفف طوری پیشنهاد می شود که کمترین ابهام ممکن را داشته باشد؛ یعنی کمترین کلمات ممکن همین مخفف را داشته باشند.

3- بهبود: چند بهبود در ذهنم است که در اولین فرصت به سورس کد اضافه خواهم کرد. برای مثال بهتر است مخفف پیشنهادی برخی قواعد واجی را هم رعایت کند. همچنین ممکن است کدها بهینه نباشند. این مورد را به حساب این بگذارید که در مسیر یادگیری پایتون هستم!

4- تولید ترکیبات یک مجموعه: قطعه کد مربوط به تابع Combinations را از اینجا برداشتم.

در ادامه سورس کد این پیشنهاد دهنده را می توانید ببینید:
import re;


def Combinations(iterable, r):
pool = tuple(iterable)
n = len(pool)
if r > n:
return
indices = range(r)
yield tuple(pool[i] for i in indices)
while True:
for i in reversed(range(r)):
if indices[i] != i + n - r:
break
else:
return
indices[i] += 1
for j in range(i+1, r):
indices[j] = indices[j-1] + 1
yield tuple(pool[i] for i in indices)

def Count(username):
pattern = r"(\w*";
for ch in username:
pattern = pattern + ch + r"\w*"
pattern += ")";
n = len( re.findall( pattern,text,re.IGNORECASE) );
return n

# Get inputs
username = raw_input("First name:");
sub_len = input("Username length:");

# Initialize
minCount = -1;
minSubStr = "";
file = open("names.dic","r");
text = file.read();

#
for substr in Combinations(username,sub_len):
jsubstr = "".join(substr);
n = Count( jsubstr )
print jsubstr + "\t" + str(n)
if( minCount==-1 or n<minCount ):
minCount = n;
minSubStr = jsubstr;

# Print result
print minSubStr + "\t" + str(minCount)

file.close();


Repository این برنامه را می توانید در این آدرس پیدا کنید:
https://github.com/coybit/Abbreviation-Username-Recommendation

لیست نام ها از لینک زیر دانلود شده است (در این لینک چند لیست جالب دیگر هم پیدا می شود) :

ابزار مورد علاقه من برای تست Regex ها: