ترجمه متون در کامند لاین

میلاد زنگنه این پروژه بامزه رو برام فرستاده:

یک برنامه صد خطی AWK بازمتن و آزاد که می‌تونه سرویس ترجمه گوگل رو صدا بزنه و از همون خط فرمان، جمله‌های شما رو ترجمه کنه. کافیه
فایل فشرده رو دریافت کنین و بازش کنین و نصبش کنین و صداش بزنین:

jadi@funlife:/tmp$ axel -q https://github.com/soimort/google-translate-cli/archive/master.tar.gz
jadi@funlife:/tmp$ tar xf master.tar.gz 
jadi@funlife:/tmp$ ./google-translate-cli-master/translate "سلام گیک. حالت چطوره؟"
Hi geek. How are you?
jadi@funlife:/tmp$

البته قبلش باید بسته gawk رو نصب کرده باشین.

قرعه کشی و اعلام اسامی برندگان جایزه‌های مسابقه پیش بینی سورپرایز اوبونتو

دو سه روز قبل مسابقه ای داشتیم برای حدس سورپرایز اوبونتو و بعدش هم کسانی که جواب تا حدی درست داده بودن و قرار بود در قرعه کشی حضور داشته باشن، اعلام شدن. حالا لحظه قرعه کشی فرا رسیده! برنامه قرعه کشی رو علیرضا داوطلبانه نوشت و من هم همون رو استفاده می‌کنم. برنامه نسبتا عجیبی است که این فایل رو می‌گیره:

 3 AliBehjati
 3 Mohammad
 3 Hesam
 1 Ehsan
 1 Amir1207
 1 Ali1217
 6 Ali0202
 1 Voltan
 2 Amir0119
 1 Saeed
 2 Jamshid
 2 Matin
 3 Narcissus
 2 MassoudM

و بعد از ساخت یک فایل جدید که توش هر اسم به تعداد شانسش تکرار شده و صدا زدن پایتون برای عدد رندم، یک خط اتفاقی رو نشون می ده. برنامه درسته و ما هم از همین استفاده می کنیم. البته من خروجی رو با cowsay ایجاد کردم که هیجان انگیزتر بشه (اگر این دستور رو بلد نیستین همین الان یاد بگیرین و لذتش رو ببرین!). سورس برنامه در نهایت اینه:

[jadi@jedora ghore.sh]$ cat ghore_keshi.sh 
#! /bin/bash

if [ ! -f "gklist" ]; then
    echo "Write names and scores to 'gklist' file and execute this script at the same directory"
    exit 1
fi

if [ ! -d /tmp/gk ]; then
    mkdir /tmp/gk
else
    rm /tmp/gk/*
fi
cp "gklist" /tmp/gk
cd /tmp/gk

for ((i=0; i<`cat "gklist" | wc -l`; i++)); do
    S="`cat "gklist" | head -$[i+1] | tail -1`"
    NUM="`echo "$S" | awk '{ print $1 }'`"
    NAME="$(cat "gklist" | head -$[i+1] | tail -1 | cut -d\" -f2)"
    for ((j=0; j<$NUM; j++)); do
	echo $NAME >> result
    done
done

LL="`cat "result" | wc -l`"
RANDNUM="`python -c "import random;print(random.randint(1, $LL))"`"
barande=`cat "result" | head -$RANDNUM | tail -1 | cut -d" " -f2 `
cowsay Winner of $1 $barande

نکته بسیار مهم اینه که در یک رای گیری / قرعه کشی و … تا وقتی از نرم افزار آزاد و پروسه‌های شفاف استفاده نشده یعنی یک جای کار می لنگه (منظور فقط تقلب و خباثت نیست. این لنگش(!) ممکنه سواد یا شعور یا دسترسی فنی برگزار کننده باشه).

حالا که همه پروسه‌ها شفافن و هر کسی هم به سورس برنامه انتخاباتی دسترسی داره، می ریم سراغ قرعه کشی. اگر یک سیستم درست داشتیم این بخش هم باید به شکل مستقیم در اینترنت پخش می شد ولی من به خاطر لنگیدن اینترنت درست، ضبطش کردم و آفلاین گذاشتمش روی اینترنت که شبهات به حداقل برسه. با یک خط دستور دوبار برنامه رو اجرا می کنیم برای دو جایزه: اولی تی شرت و دومی ماگ. دعا هم کنیم که برنده تکراری در نیاد! ویدئوی برگزاری رو ببینین؛ با تشکر از شرکت معظم www.aivivid.com که اسپانسری تی شرت مجری رو بر عهده داشتن



اگر هم حاکم هاتون تصمیم گرفتن که دیدن ویدئو براتون خوب نیست ونمی تونین از برنده ها مطلع بشین نگران نباشین! خودم به شکل متنی هم براتون برنده ها رو اعلام می کنم:

  • برنده اول مسعود.ام تنها شرکت کننده ما از گوگل پلاس با شانس ۲ که برنده این تی شرت میشه:
  • و برنده دوم متین – اونهم با شانس دو – که این ماگ رو از اسپانسر مسابقه یعنی سیتو دریافت می کنه

با برندگان عزیز برای گرفتن آدرس و ارسال جوایزشون تماس گرفته می شه (: خوش باشین تا مسابقه بعدی

پ.ن. ویدئو رو با این دستور گنو/لینوکسی کوچیک کردم

 $ffmpeg -i DSCN3085.AVI -ab 56k -ar 22050 -b 300k -r 15 -s 480x360 DSCN3085.flv                             

چرا گنو/لینوکس را دوست دارم: بررسی سال های تولد در اطلاعات افشا شده ۳۰۰۰۰۰۰ کارت بانکی

در بخش کامنت های مطلب نقدی بر برنامه بی بی سی در مورد جریان انتشار سه میلیون کارت اعتباری ، همایون گفته بود که:

درود. کارهای آماری جالبی میشه با داده‌ها انجام داد. به عنوان مثال احتمال این که آدمها تاریخ تولدشون رو به عنوان رمز انتخاب کنن بالاست. به دنبال ۱۳۶ بگردبن در فهرست رمزها و مقایسه‌اش کنین با هر عدد ۳ رقمی دیگه‌ای. (۱۳۷ و ۱۳۵ و ۱۳۴ هم تعدادشون بالاست). من اگه دنبال دزدی بودم از اینجا شروع میکردم.

خب ایده بسیار جالبیه و من هم امروز یک ساعتی وقت اضافی دارم برای دستگرمی لینوکس و برنامه نویسی و نوشتن یک مطلب در مورد چرا لینوکس رو دوست دارم و همینطور دادن فرصت به کسانی که می خوان مهارت های عملی خودشون توی خط فرمان رو بالا ببرن و مثل یک هکر، به ابزارشون مسط باشن.

اگر شما علاقه ای به خط فرمان یا حوصله اش رو ندارین و فقط نتیجه کار رو می خواین… سریع اسکرول کنین پایین تا برسین به نمودارهای آخر (:

اگر هنوز با من هستین بگم که اینکارها دقیقا به همین ترتیب انجام شدن و مطمئنا روش های بهتری دارن…. در اصل شما دارین چرک نویس رو می خونین تا ببینین قدم ها چطوری برداشته شدن.

در قدم اول همه صفحات بانک تجارت رو باز می کنم، با ctrl+A متنشون رو کپی می کنم و توی یک ادیتور متنی paste می کنم. من توی لینوکس برای اینکار از gedit استفاده کردم که ادیتور ساده و دم دستی گنوم است… مشخصه که اگر توی ویندوز بودم خود این یک ماجرا بود که کدوم ادیتور ممکنه بتونه این پیست رو قبول کنه و آخ نگه.

به خاطر کپی پیست من فقط متن های توی صفحه ها رو دارم… چیزهایی مثل این:

با یک دستور تمام خط هایی که توشون + هست رو جدا می کنیم. اینها خط های حاوی پسورد هستن:

grep "+" all_tejarat.txt > only_hesab_and_pass

اوه اوه! شد این:

و ادیتور توی باز کردنش یک آخ ملایمی گفت (سی ثانیه ای طول کشید تا باز بشه) چون دوستمون حتی یک انتر هم نزده و در نتیجه با خطوطی طرف هستیم که یک میلیون کاراکتر در هر خط نوشته شده‌ (: قاعده طبق گفته خودش اینه:

رمز مخفي , شماره کارت + رمز مخفي , شماره کارت + رمز مخفي , شماره

پس من برای راحت کردن کارم، همه + ها رو تبدیل می کنم به سر خط:

jadi@jubung:~/Desktop$ sed -e "s/\s+[+]*\s*/\n/g" only_hesab_and_pass > har_password_yek_khat
jadi@jubung:~/Desktop$ head har_password_yek_khat 
رمز مخفي , شماره کارت
رمز مخفي , شماره کارت
رمز مخفي , شماره کارت 6273531000000002,73251531609013
6273531000000087,42984601252954
6273531000000105,90683196772477 6273531000000145,14810051866743
6273531000000146,61558146155078
6273531000000150,14869351127492 6273531000000151,87078051710776
6273531000000201,17221491685028
6273531000000222,32833487680537 6273531000000232,06865382135692
6273531000000232,69595659033276

راستش درست نفهمیدم چی شد! درست کار نکرد ولی بد هم نبود… حالا یک قدم دیگه باید تیکه تیکه کنم این فایل رو. فاصله ها رو به سر خط تبدیل می کنم‌ (:

jadi@jubung:~/Desktop$ sed -e "s/ /\n/g"  har_password_yek_khat > har_password_yek_khat_2
jadi@jubung:~/Desktop$ head -20 har_password_yek_khat_2 
رمز
مخفي
,
شماره
کارت
رمز
مخفي
,
شماره
کارت
رمز
مخفي
,
شماره
کارت
6273531000000002,73251531609013
6273531000000087,42984601252954
6273531000000105,90683196772477
6273531000000145,14810051866743
6273531000000146,61558146155078

و حالا همه چیز مرتبه. فقط باید پسوردها رو جدا کنم. خط هایی که توشون , هست رو جدا می کنم و می دم به یک دستور دیگه که در هر خط، اعداد اول خط تا رسیدن به کاما رو حذف می کنه. پس می مونه فقط پسوردها. می تونین نگاه کنین که چطوری با | خروجی یک دستور رو دادم هب ورودی دستور بعدی:

jadi@jubung:~/Desktop$ grep  ".," har_password_yek_khat_2 | sed "s/^.*,//" > all_passwords
jadi@jubung:~/Desktop$ head all_passwords 
73251531609013
42984601252954
90683196772477
14810051866743
61558146155078
14869351127492
87078051710776
17221491685028
32833487680537
06865382135692

حله (: ببینیم چند تا پسورد داریم:

jadi@jubung:~/Desktop$ wc -l all_passwords 
118499 all_passwords

صد و هجده هزار عدد چهارده رقمی داریم که پسوردها توشونه. حالا می ریم سراغ بررسی نظریه اصلی:

مردم احتمالا سال تولدشون رو به عنوان پسورد می ذارن.

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

#!/usr/bin/perl

while ($userinput =  ) {
	chomp ($userinput);
	for($i = 0; $i <= 10 ; $i++) {
		print  substr $userinput, $i, 4;
		print "\n";
	}
}

این برنامه ورودی رو می خونه و قسمت های چهار رقمی رو ازش جدا می کنه:

jadi@jubung:~/Desktop$ echo "73251531609013" | ./find_numbers.pl 
7325
3251
2515
5153
1531
5316
3160
1609
6090
0901
9013

درست کار می کنه پس برنامه رو کامل می کنم:

#!/usr/bin/perl

@passes = ();
for($i = 0; $i <= 9999 ; $i++) {
	$passes[$i] = 0;
}


while ($userinput =  ) {
	chomp ($userinput);
	for($i = 0; $i <= 10 ; $i++) {
		$thispass = substr $userinput, $i, 4;
		$passes[$thispass] += 1;
	}
}

for($i = 0; $i <= 9999 ; $i++) {
	print $i, ",",$passes[$i],"\n";
}

این برنامه همه ورودی رو می خونه و از هر خط همه پسوردهای محتمل رو خارج می کنه و می شمره و می ره سراغ خط بعدی و در نهایت می گه هر عدد چند بار ممکن بوده به عنوان پسورد انتخاب شده باشه. بعد از اجرا خروجی اش چیزی شبیه اینه:

jadi@jubung:~/Desktop$ cat all_passwords | ./find_numbers.pl  > all_passwords_charts
jadi@jubung:~/Desktop$ head all_passwords_charts 
0,163
1,150
2,135
3,122
4,137
5,141
6,123
7,138
8,122
9,133

حالا که اینها رو داریم کافیه بریم سراغ برنامه LibreOffice برای کشیدن نمودارها. مثلا این نمودار اول است:

دیده می شه که یک جاهایی پیک داریم. بذارین یک سورت هم بکنم به ترتیب فراوانی و یک نمودار دیگه از صد تا از پرکاربردترین ها بکشیم ببینیم چی در می یاد.

اوه! نظریه دوستمون تقویت شد: مردم از سال تولد برای پسوردها استفاده می کنن (: واضح بود ولی خب از این بازی لذت بردیم و تازه یک نظریه رو هم هرچند کم،‌ تقویت کردیم. همینطوره ترکیب های «خوش دست» روی کیبورد (:

نظرتون چیه برای اختتامیه یک آمار هم بگیریم از تعداد ارقام؟ مشخصه که یک تغییر کوچیک در برنامه است فقط:

#!/usr/bin/perl

@passes = ();
for($i = 0; $i <= 9 ; $i++) {
	$passes[$i] = 0;
}


while ($userinput =  ) {
	chomp ($userinput);
	for($i = 0; $i <= 13 ; $i++) {
		$thispass = substr $userinput, $i, 1;
		$passes[$thispass] += 1;
	}
}

for($i = 0; $i <= 9 ; $i++) {
	print $i, ",",$passes[$i],"\n";
}

و نتیجه:

jadi@jubung:~/Desktop$ cat all_passwords | ./find_numbers.pl  > all_digits
jadi@jubung:~/Desktop$ cat all_digits 
0,157054
1,180318
2,169604
3,175258
4,166898
5,169252
6,162562
7,158727
8,160099
9,159214

هاه.. می بینین که احتمال استفاده از ۷ و ۹ پایینه (این رو قبلا هم شنیده بودم) و احتمالا استفاده از یک و سه بالا (: توجه داریم که در صورت درست بودن الگوریتم اعداد رندم استفاده شده برای «مخفی کردن» پسوردها، یک نویز سفید اون پایین داریم که احتمالا مساوی پخش شده.