انسان، تکنولوژی و زمان

مفهموم «زمان» به طور مستقل میتونه عنوانی برای ساعت‌ها بحث و گفت‌و‌گو باشه. آیا زمان بُعدی است کاملا مستقل؟ تاثیراتی که کشفیات انیشتین روی مفهوم زمان گذاشت چه بود؟ و بیشمار سوالهایی که میشه مطرح کرد و تبدیلش کرد به میدون مبارزه‌ی بی‌نظیری بین فیزیک‌دان‌ها، فیلسوف‌ها و اصولا هرکسی که کمی به مفاهیم اینچنینی علاقه داره.

من نه فیزیک‌دانم و نه فیلسوف. پس طبیعیه که مطالعه و اطلاعات عمیق و خاصی در خصوص ماهیت «زمان» ندارم. چیزی که من رو به مفهوم زمان خیلی علاقه‌مند کرد، در وهله‌ی اول ارتباطش با نور بود! که خب متفاوته با چیزی که اینجا میخوام مطرح کنم، و در وهله‌ی دوم ایده‌ای بود که توی کتاب «انسان خردمند» باهاش آشنا شدم و بعد با مرور زمان بیشتر و بیشتر بهش فکر کردم.

اینطور که به نظر میاد با پیشرفت تمدن، همواره سرعت زندگی آدم‌ها بیشتر شده و در نتیجه اهمیت زمان روز به روز افزایش پیدا کرده. به طور مثال، انسان شکارچی و خوراکجویی رو فرض کنید که راه زندگی و زنده‌موندش وابسته به اینه که در روز به دنبال جمع کردن میوه و شکار حیوانات باشه و در شب به استراحت بپردازه. در این شرایط، هیچ موجودی نیاز به داشتن فهم خاصی از زمان نداره. بالاترین طبقه‌بندی زمانی از نظر یک انسان اینچنینی، درک تفاوت روز و شبه. بعدها که انسان‌ها یکجانشین و کشاورز شدند، اهمیت زمان کم‌کم بیشتر شد. یک انسان کشاورز باید درک میکرد که فصل‌ها چه هستند، چه روزهایی احتمال بارش باران بیشتره و … انسان کم‌کم درکی انتزاعی از مفهوم «زمان» پیدا کرد. یعنی اساسا انسان خوراکجو نیازی به داشتن درک از متغیر زمان به شکل امروزی نداشت. امروزه بچه‌های ما در سنین ۵ یا ۶ سالگی درک بسیار بالاتری از مفهوم زمان نسب به یک انسان خوراکجوی اولیه دارند و این در صورتیه که هردوی اینها از ژنتیک یکسانی برخوردارند.

ادامه مطلب

الگوریتم‌هایی که شما رو اعدام می‌کنن!

تیتر عجیب یک خبر در SienceMag مشتاقم کرد تا کمی بیشتر درمورد نرم‌افزارهای دادگاهی سرچ کنم. تیتر خبر اینه:

یک نماینده‌ی ِ مجلس ِ آمریکا خواستار بررسی دقیق‌تری پیرامون الگوریتم‌هایی است که در دادگاه‌های جنایی استفاده می‌شوند

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

https://www.nature.com/articles/d41586-018-05469-3 :منبع عکس
https://www.nature.com/articles/d41586-018-05469-3 :منبع عکس 

مشکل اینه که شرکت‌های مختلفی وجود دارن که این نرم‌افزارها رو تولید می‌کنن و اینطور که پیداست اکثر این نرم‌افزارها متن‌باز و آزاد نیستن و شرکت‌های سازندشون حاضر نیستن تا سورس کد این برنامه‌ها رو در اختیار دیگران (مثل تیم مدافعین متهمان و دادگاه) قرار بدن و حتی حاضر نیستن تا درمورد نحوه‌ی نتیجه‌گیری این نرم‌افزارها هم داده‌های مهمی رو ارائه کنن و دلایل متعددی هم برای این کار دارن، از جمله این که نمیخوان شرکت‌های رقیب از تکنولوژیشون سر در بیارن.
حالا فرض کنید که آدما می‌تونن به خاطر خروجی‌هایی که این نرم‌افزارها و الگوریتم‌ها ارائه‌می‌کنن، به زندان و یا حتی مرگ محکوم بشن! و حتی در بعضی مواقع تنها شواهد موجود در پرونده نتایج همین الگوریتم‌هاست! و خب الان صدای خیلیا از جمله یک نماینده مجلس آمریکا به نام Mark Takano دراومده که داره تلاش می‌کنه تا لایحه‌ای رو تصویب کنه که اجازه میده روی این نرم‌افزارها بررسی دقیقی انجام بشه تا چیزهای زیادی مثل خطا و یا این که آیا این نرم‌افزارهای نسبت به اقلیت‌ها تعصبی دارن یا نه مشخص بشه.

از قرار معلوم یکی از مهم‌ترین دسته‌های این نرم‌افزارها اسمش هست probabilistic genotyping software که ترجمه‌ی تحت‌الفظیش میشه نرم‌افزار ژنوتیپ احتمالی که برای تشخیص و تطبیق DNA یک فرد مضنون در بین DNAهایی که از صحنه‌ی جرم جمع‌آوری شده استفاده میشه. از اونجا که DNAهای صحنه‌ی جرم ممکنه آسیب‌دیده باشه و یا با مواد دیگه‌ای آلوده شده باشه و حتی حاوی چند DNA مختلف باشه، تشخیص DNAهای موجود در اون و این که آیا DNA فرد خاصی در اون نمونه هست یا نه همیشه کار راحتی نیست و بنابراین از این نرم‌افزارها استفاده میشه تا با یک احتمال مشخص وجود یک DNA خاص در اون نمونه تعیین بشه.

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

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

و خب جدای همه‌ی این جزئیات چیزی که آدمو به فکر میبره، اینه که یه روزی ممکنه همه‌ی چیزی که ما به عنوان دادگاه، قاضی و پروسه‌ی عادلانه‌ی قضاوت می‌شناسیم، با یکسری الگوریتم و هوش‌مصنوعی جایگزین بشه!
سناریوی بدترش اینه که فرض کنیم نرم‌افزارهایی در دادگاه‌ها استفاده بشن که از شبکه‌های عصبی مصنوعی استفاده کنن. خب مشکلش چیه؟ حتی اگه شرکت سازندش اجازه هم بده، نمی‌تونیم از درونش سردربیاریم! فرض کنید روزی رو که یک جعبه‌ی سیاه بزرگ وجود داره و متهم‌ها توی صف ایستادن و وقتی نوبتشون میشه از اون جعبه یک حکم پرینت میشه و میاد بیرون!

 

لینک نوشته در ویرگول: virgool.io/@mahdavipanah/klnk6pffkmhw

رابطه‌ی عاطفی ما با خونه‌هامون

عکس صرفا تزئینیه و با گوشی در روستای قمصر گرفتم
عکس صرفا تزئینیه و با گوشی در روستای قمصر گرفتم

این اولین بارم نیست. در اصل این دومین خونه‌ای بود که تاحالا توش زندگی کردم. خونه‌ی اولمون یک خونه‌ی سازمانی بود که تا هشت سالگیم اونجا بزرگ شدم. خونه‌ای ساده با حیاطی بزرگ و یه باغچه‌ی نسبتا پر گل و گیاه و درخت گل یاسی که هیچوقت از یادم نمیره. درخت گل یاسی که پدربزرگ خدابیارزم همیشه بهش رسیدگی می‌کرد. هنوز که هنوزه هرموقع بوی گل یاس به دماغم می‌خوره ناخودآگاه پرت میشم به همون حیاط، همون کوچه و همون دوران کودکی. خداحافظی با خونه‌ی اول برام خیلی ساده بود. سنم کم‌تر بود و بنابراین مثل آدم‌بزرگا هنوز درگیر خاطرات نبودم و وابستگی مسئله‌ی جدی‌ای به حساب‌نمیومد؛ مخصوصا برای خونه‌ای درب و داغون و مخصوصا برای منی که بسیاری از زمان‌های کودکیم رو توی خونه‌ی خالم گذرونده بودم. تصاویری که از اون دوران توی ذهنمه خیلی درهم و برهم و محوه؛ ملغمه‌ای از باغ اونور کوچمون و خونه‌ی همسایه‌ی کشاورزمون که اسمش آقای «چرب‌دست» بود و همچنین کوچه‌ای که انتهاش خاکی بود و برای من ِ پنج شش‌ساله حکم انتهای دنیا را داشت. جرئت می‌طلبید رفتن تا آخر اون کوچه، اما ارزششو داشت، چون دقیقا همون‌جایی که جاده‌ی خاکی شروع می‌شد جائی بود که سمت راستش راه داشت به یک محوطه‌ی باغ‌مانند و باز که برکه‌ی آب توش جاری بود و درخت توتی اونجا بود که از بهترین شادی‌های بچه‌های محل محسوب می‌شد. توت‌های سفید و درشت که شیرینیش هنوز زیر زبونمه.

هشت سالم که بود ساخت خونه‌ی جدید شروع شد. خونه‌ای که در کاشان، شهر کنار زادگاهم واقع شده بود. در همون آغاز ساخت خونه، برای این که من با محیط شهر جدید وفق بگیرم و تا زمانی که قراره ساکن بشیم، دوستایی برای خودم داشته باشم و شروع زندگی در شهر جدید ساده‌تر باشه، سال دوم دبستان رو در مدرسه‌ای جدید در کاشان شروع کردم، دبستان ملامحسن. صبح‌ها به همراه داییم مسیر نیم‌ساعته تا کاشان را طی می‌کردم و بعد از تعطیلی مدرسه، پیاده به کارگاه نجاری دائیم که تا دبستان فاصله‌ی کمی داشت می‌رفتم و بعد از اتمام کار دایی، باهم برمی‌گشتیم.
خونه‌ی جدید و مدرسه‌ی جدید و کارگاه دائیم در یک محله بود و بنابراین این سه مکان اصلی‌ترین خاطرات اون دوران من رو در خودش جای میده. بعد از تعطیلی مدرسه و مراجعه به کارگاه داییم، بعضی روزها به خونه‌ی جدید می‌رفتیم و به دایی در انجام کارهای چوبی خونه‌ی جدید (که دیگه داشت تکمیل می‌شد) کمک می‌کردم. منگنه‌های پارکت کف خونه رو با مغار بیرون می‌کشیدم و بعد دایی جای اونارو صیقل می‌کرد و رنگ میزد. این روند ادامه داشت و من، تولد و رشد خونه‌ی جدید رو از نزدیک شاهد بودم. خونه‌ای که داشت همپای کودکی من بزرگ می‌شد و مکانی رو آماده می‌کرد که تمام دوران نوجوانی و ابتدای جوانیم رو در اون بگذرونم.

از اون روزها ۱۶ سال ناقابل می‌گذره و الان که در حال نوشتن این کلماتم، کمتر از ۲۴ساعته که در خونه‌ای جدید (که خونه‌ی سومم حساب می‌شه) ساکن شدیم. خونه‌ای که آپارتمانیه و محوطه‌ای بزرگ و مشترک بین چندتا بلوک داره و تعداد همسایه‌هامون چند‌ده برابر خونه‌ی قبلیه!
اما این‌ها دلیل نمی‌شه تا هنوز خونه‌ی جدید رو بیشتر از خونه‌ای که ساختنش رو ذره‌ذره شاهد بودم، دوست‌داشته‌باشم. خونه‌ی قبلیمون رو کماکان داریم، اما قراره دایی بزرگترم، همونی که صاحب کارگاه نجاری بود، اونجا ساکن بشه. اول که این خبر رو شنیدم واقعا بهم ریختم! ترکیبی از حس حسادت، عصبانیت و غم داشت دیوونم می‌کرد! و جالبتر این که این اولین بار بود که همچین حسی رو، اون‌هم برای یک ساختمون(!) تجربه می‌کردم. یه جوری انگار منی که با داییم خونه رو ساخته بودیم، بعد از ۱۶ سال داشت از چنگم درش میاورد 🙂 بیشتر که فکر کردم همه‌چیز یادم اومد. تمام اون ۱۶‌سال مثل فیلم از جلوی چشمام گذشت. تمام خاطرات ریز و درشت، گریه‌ها و خنده‌ها و تک‌تک ملاقات‌ها و ثانیه‌هایی که من ِ ۸ ساله رو تبدیل کرده بود به یه جوون ۲۴ ساله. و بعد فهمیدم که چرا ناراحتم، چرا حسادت می‌کنم و چرا عصبانیم.

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

قسمت خوب این تجربه، رشد نگاه من به خونه‌ها بود! و درک اهمیتشون در زندگیامون. چون بیشتر که فکر کردم متوجه شدم چقدر خونه‌ها و ساختمونای مختلفی وجود داره که من وقتی بهشون فکر می‌کنم، موجی از احساسات و خاطره‌ها بهم سرازیر میشه. نهایتا هر خاطره‌ای جایی برای ساخته‌شدن می‌خواد. هر خونه‌ای پناهگاه کلی آدم و خاطره‌هاشونه، گاو‌صندوقی که ما توش زندگی می‌کنیم و ذره‌ذره لحظه‌هامون رو درش به امانت می‌ذاریم و گاهی اونو می‌سپاریم به آدمای جدید تا اونا هم جایی داشته باشن برای ساختن خاطرات جدیدشون 🙂

 

لینک نوشته در ویرگول: virgool.io/@mahdavipanah/homes-d9jaiprxv84o

چرا خواندن کتاب «انسان خردمند» را توصیه می‌کنم؟

بعد از خواندن نوشته‌ای با عنوان «چرا کتاب انسان خردمند را نمی‌خوانم؟» که MAHSA MOJDEHY در صفحه‌ی ویرگولشان منتشر کرده بودند، تصمیم گرفتم جوابیه‌ای کوتاه بنویسم که هم پاسخی به نوشته‌ی ایشان باشد و هم توصیه‌ای به خواندن این کتاب از نگاه بنده. پس توصیه می‌کنم ابتدا نوشته‌ی ایشان و سپس ادامه‌ی این متن را بخوانید.

ترجمه‌ی فارسی کتاب «انسان خردمند» از انتشارات «فرهنگ‌نشر‌نو» (منبع تصویر: kafebook.ir)
ترجمه‌ی فارسی کتاب «انسان خردمند» از انتشارات «فرهنگ‌نشر‌نو» (منبع تصویر: kafebook.ir)

 

نوشته‌ی شما از جهت صادقانه بودن قابل ستایش است اما ایراداتی جدی به بررسی شما درمورد این کتاب وارد است.

اولین نکته‌ای که خود همیشه سعی در رعایتش دارم این است که بدون خواندن هیچ کتابی، درموردش نظر نمی‌دهم و اولین ایراد بنده به نوشته‌ی شما عنوان آن است. کتاب‌ها باید خوانده شوند، درک شوند و سپس نقد شوند. البته که می‌توان در نقد یک کتاب به مخاطب توصیه کرد تا انرژی و وقت خود را صرف مطالعه‌ی آن نکند ولی این توصیه از زبان کسی که خود نیز کتاب را نخوانده، زیاده‌روی در پیش‌داوری است. البته که این امر یک انتخاب شخصی است و البته که انسان می‌تواند بدون شناخت یک موضوع، نظر شخصی خود را درموردش بیان کند و حتی گاهی این نظرات صحیح نیز هستند، اما قضاوت‌های اینگونه معمولا با خطای زیادی همراه‌اند.

«کلی گویی همیشه ضد جذابیت است»:
هرکتابی که روی جلد آن «تاریخ بشر» حک شده باشد، حتی اگر کتابی ۱۰۰ جلدی باشد، این ایراد شما بر آن وارد است. نویسنده به هیچ عنوان تلاشی در جهت دادن شناختی عمیق از ده‌ها هزارسال تاریخ بشر به خواننده نمی‌کند بلکه تلاش می‌کند که بینش و روایتی که خود از مطالعاتش به دست‌آورده‌است را با نثری روان، درست و البته علمی (تاکیید میکنم، «علمی») به خواننده‌ی علاقه‌مند منتقل کند و در اصل به جای این که شما به این کتاب به عنوان مرجعی برای شناخت عمیق نگاه کنید باید به آن به مثابه‌ی یک نقشه‌ی راه بنگرید.

«وقتی با یک کتاب عکس های زیادی گرفته می شود، یک جای کار می لنگد»:
حرفتان را تا حدودی قبول دارم اما به نظرم جمله‌تان باید کمی تغییر کند: «وقتی با یک کتاب عکس های زیادی گرفته می شود، باید شک کرد که شاید یک جای کار می لنگد.» این که کتابی پرفروش و پرخواننده می‌شود می‌تواند معلول عوامل گوناگونی مثل معرفی شدن آن توسط چهره‌ی سرشناس در بین مردم، بازاریابی قوی ناشر، زمان مناسب انتشار و … باشد. پس آیا هر کتابی که بر سر زبان‌ها می‌افتد به این معناست که از محتوا خالی است و کتابی است بازاری؟ به عقیده‌ی بنده قطعا خیر. همچنان که در بسیاری از کشور‌های دیگر دنیا بر خلاف کشور ما که معمولا کتاب‌هایی که سرشان به تنشان میارزد تیراژشان از چندهزارتا (تازه اگر خوش‌شانس باشند و اجازه‌ی چاپ پیدا کنند) بالاتر نمی‌رود، می‌توانند کتاب‌هایی پرفروش شوند و مخاطبان زیادی در بین مردم پیدا کنند.

«… و یک طرف دیگر مخالفانی هستند که می گویند کتاب زیاده از حد عقلانی است.»:
کاملا درست است! کتاب یک کتاب علمی است که در انتهای آن ۲۲ صفحه به ذکر منابع اختصاص دارد! پس اساسا خواننده‌ای که عقلانی بودن یک کتاب، آن هم با موضوع «تاریخ بشر» را، از نقاط ضعف آن می‌داند، به طور واضح موضوع علم برایش هنوز حلاجی نشده باقی‌مانده و اتفاقا شاید خواندن «انسان خردمند» بهترین نقطه‌ی شروع فهم او از رابطه‌ی انسان و علم در تاریخ باشد.

به عقیده‌ی بنده کتاب «انسان خردمند» کتابی است کاملا علمی و برپایه‌ی منابع قابل اتکا که بزرگترین برتری خود را در روایتی حقیقی و در عین حال جذاب پیدا کرده است.
هنر نویسنده نه در کشف حقایق تاریخ بشر (که خود نیز چنین ادعایی ندارد و منابع فراوانی که نویسنده به آن‌ها ارجاع دارد هم شاهدی بر همین مدعاست) که در پیدا کردن یک خط داستانی و روایت تاریخی بی‌نظیر در دل این حقایق است و می‌توان گفت با این که مخاطب کتاب مخاطبی غیرتخصصی است، اما به هیچ عنوان از ارزش علمی کتاب چیزی کم نمی‌کند و کتاب حتی برای یک خواننده‌ی پرمطالعه در حوزه‌ی مورد نظر نیز می‌تواند بسیار خواندنی، پرمحتوا و آموزنده باشد.

 

لینک نوشته در ویرگول: vrgl.ir/4GXaI

چگونه به شکل امن گذرواژه‌ها را ذخیره کنیم؟

جواب خلاصه: از bcrypt استفاده کنید.

 

چرا از MD5، SHA-1، SHA256، SHA512، SHA-3 و … استفاده نکنیم؟

تمام الگوریتم‌های نامبرده، توابع هش ِ (به انگلیسی: hash function) همه‌منظوره هستند که طراحی شده‌اند تا حجم عظیمی از داده‌ها را در کم‌ترین زمان ممکن خلاصه‌سازی کنند. [مترجم: به طور مثال، یک رشته‌ی متنی بزرگ را به متنی کوچک تبدیل کنند]. این بدین معناست که این الگوریتم‌ها برای اطمینان از صحت داده‌ها عالی و برای ذخیره‌ی گذرواژه کاملا بدردنخور هستند.

یک سرور مدرن، توانایی هش‌کردن ۳۳۰مگابایت داده را در هر ثانیه، توسط الگوریتم MD5 دارد. اگر کاربران شما گذرواژه‌هایی دارند که همه به حروف کوچکند، از حروف و ارقام تشکیل شده‌اند و طولشان ۶ است، شما به راحتی می‌توانید تمام رمز‌های عبور ممکن (با مشخصات گفته‌شده) را در چیزی حدود ۴۰ ثانیه امتحان کنید.

و این حتی بدون خرج کردن یک قِران است!

اگر توانایی خرج کردن ۲۰۰ دلار آمریکا و استفاده از CUDA برای یک الی دو هفته را داشته باشید، می‌توانید سوپر کامپیوتر کوچکی برای خود فراهم کنید که توانایی امتحان کردن چیزی درحدود ۷۰۰٫۰۰۰٫۰۰۰ گذرواژه در ثانیه را دارد. و با این توان، شما می‌توانید رمز‌های عبور با شرایطی که قبلا گفتیم را نه هر ۴۰ ثانیه بلکه در هر ثانیه بشکنید!

salt‌ها به شما کمکی نخواهند کرد

توجه به این نکته مهم است که بدانید، saltها برای جلوگیری از حمله‌های لغت‌نامه‌ای (به انگلیسی: dictionary attack) و حملات بروت فورس‌ (به انگلیسی: brute-force attack) کاملا بدردنخورند. با این فرض که مهاجم salt و هش ِ دیتابیس شما را دارد، حتی اگر saltهای بسیار بزرگ هم استفاده کنید، کماکان تاثیری روی این موضوع که مهاجم با چه سرعتی توانایی تست کردن گذرواژه‌های کاندیدا را دارد، نخواهد گذاشت.

با salt یا بدون salt، اگر شما از یک تابع هش ِ همه‌منظوره، که برای سرعت طراحی شده، استفاده کنید، به دردسر بزرگی افتاده‌اید.

bcrypt مشکل را حل می‌کند

چگونه؟ به زبان ساده، فوق‌العاده کند است. bcrpyt از نوعی از الگوریتم Blowfish استفاده می‌کند و چیزی به نام ضریب کار را معرفی می‌کند که این امکان را می‌دهد تا بتوان تعیین کرد که تابع هش تا چه اندازه هزینه‌بر باشد. به همین دلیل bcrypt می‌تواند پابه‌پای قانون مور پیش برود. هرچه کامپیوتر‌ها سریع‌تر می‌شوند شما می‌توانید ضریب کار را زیادتر کنید و بدین‌ترتیب هش‌کردن نیز کندتر خواهد شد.

به طور مثال، bcrypt چقدر از MD5 کند‌تر است؟ به ضریب کار بستگی دارد. با ضریب کار ۱۲، bcrypt گذرواژه‌ی yaaa را روی لپ‌تاپ من در ۰.۳ ثانیه هش می‌کند. در سوی دیگر، MD5 همین کار را در کمتر از یک میکروثانیه انجام می‌دهد.

پس درمورد چیزی با مرتبه‌ی ۵ (۱۰ به توان ۵) برابر کندتر صحبت می‌کنیم. یعنی به جای شکستن هر گذرواژه تنها در ۴۰ ثانیه، این‌بار شکستن هر گذرواژه چیزی در حدود ۱۲ سال طول خواهد کشید. شاید شما به چنین حدی از امنیت نیاز نداشته باشید و الگوریتم مقایسه‌ی سریع‌تری را بخواهید، بدین ترتیب bcrypt امکان توازن بین سرعت و امنیت را برای شما فراهم می‌کند. از آن استفاده کنید.

 

متن بالا ترجمه‌‌ی من بود از مقاله‌ی How To Safely Store A Password.

این نوشته در سایت ویرگول: virgool.io/@mahdavipanah/bcrypt-sjj46uhqjx88

اهمیت رمزنگاری

مقاله‌ی زیر ترجمه‌ی من از نوشته‌ی بروس اشنایر (Bruce Schneier)، متخصص رمزنگاری، امنیت رایانه و حریم خصوصی و نویسنده‌ی اهل ایالات متحده آمریکا است و در سال ۲۰۱۶ در قالب مقاله‌ای در وب‌سایت شخصی او منتشر شده‌است.

 

با نفوذ همه‌گیر کامپیوتر‌ها و شبکه‌های کامپیوتری در دنیای امروز، سخت است که در اهمیت رمزنگاری اغراق کنیم. به طور خیلی ساده، رمزنگاری امنیت شما را حفظ می‌کند. زمانی که در حال انجام خدمات بانکی اینترنتی هستید رمزنگاری از جزئیات و گذرواژه‌های شما محافظت می‌کند. رمزنگاری از شنود مکالمات تلفنی شما جلوگیری می‌کند. اگر اطلاعات لپ‌تاپ خود را رمز می‌کنید – که امیدوارم اینکار را می‌کنید – رمزنگاری از داده‌های شما پس از دزدیده‌شدن کامپیوترتان محافظت می‌کند. رمزنگاری، پول و حریم شخصی شما را مصون نگه‌می‌دارد.

رمزنگاری از هویت مخالفان و فعالان سیاسی و مدنی در سراسر دنیا محافظت می‌کند. اگر شما یک روزنامه‌نگار باشید، برای ارتباط با منابع اطلاعاتی خود و یا اگر یک سازمان ناسودبر (به انگلیسی: NGO) باشید، برای محافظت از کار خود و یا اگر یک وکیل‌مدافع باشید، برای ارتباط خصوصی با موکل خود، به ابزاری حیاتی به نام رمزنگاری نیازمندید.

رمزنگاری از دولت ما محافظت می‌کند. رمزنگاری از سیستم‌های دولتی، قانون‌گذاران و ماموران اجرای قانون نیز محافظت می‌کند. رمزنگاری از مقامات رسمی ما که در داخل و یا خارج از کشور در حال کار هستند نیز محافظت می‌کند. در جریان بحث میان اپل و اف‌بی‌آی، برایم جالب بود که بدانم آیا جیمز کومی (رئیس وقت سازمان اف‌ابی‌آی) هیچ از این نکته اطلاع دارد که چه تعداد از ماموران خود او از آیفون استفاده می‌کنند؟ و بر قابلیت‌های امنیتی اپل برای محافظت از داده‌هایشان متکی هستند؟

ادامه مطلب

از تغییر نترسیم – به مناسبت خریده‌شدن گیت‌هاب توسط مایکروسافت

خریده‌شدن گیت‌هاب توسط مایکروسافت

امروز روز عجیبیه! خبر خریده‌شدن گیت‌هاب، دوست‌داشتنی‌ترین پلتفرم برای توسعه‌دهندگان و به طور خاص عاشقان ِ نرم‌افزار آزاد، توسط مایکروسافت، به طور رسمی تایید شد.

این خبر جدای از نگرانی‌هایی که می‌تونه برای ما بوجود بیاره (که البته به نظر من جای هیج نگرانی‌ای نیست و در ادامه هم بیشتر توضیح میدم) می‌تونه بهونه‌ای باشه تا خیلی مختصر، تاریخ تعامل توسعه‌دهنده‌ها، ابزار‌هاشون و درس‌هایی که برای ما داره رو باهم مرور کنیم.

ادامه مطلب

جاوااسکریپت: شیء انتخاب‌ها (options object) چیست؟

در جاوااسکریپت، اشیاء ِ انتخاب‌ها (که از این پس به آن‌ها options objects می‌گوییم) یک الگوی ِ معمول برای ِ فرستادن ِ آرگومان‌ها به یک تابع هستند. این مقاله به شرح ِ چگونگی ِ کار ِ آن‌ها و نیز دلیل ِ این که استفاده از آن‌ها باعث ِ افزایش ِ خوانایی ِ کد ِ شما می‌شود، می‌پردازد.

options object چیست؟

یک options object یک شیء ِ معمولی ِ جاوااسکریپت است، که داخل ِ آن‌ مجموعه‌ای از پارامتر‌هایی با اسم‌های ِ مشخص تعریف شده و به عنوان ورودی به یک تابع فرستاده می‌شود.

برای ِ مثال، تابع ِ jQuery.ajax از options object استفاده می‌کند. این تابع می‌تواند تا ۳۴ پارامتر ِ مختلف را بگیرد که تمام ِ آن‌ها اختیاری هستند.

$.ajax({
    url: "http://date.jsontest.com/",
    success: function (data) {console.log(data);},
    cache: true,
    timeout: 500
});

بدون ِ استفاده از یک options object فهم ِ این که هر پارامتر برای ِ چه کاری است، بسیار سخت خواهد بود:

$.ajax(
    "http://date.jsontest.com/",
    function (data) {console.log(data);},
    true,
    500
);

بسیاری دیگر از زبان‌های برنامه‌نویسی، امکانی دارند تحت ِ نام ِ «آرگومان‌های اسم‌دار» (به انگلیسی: named arguments) که کارایی ِ مشابهی با options objects دارند.

چه زمانی باید از option objectها استفاده کرد؟

زمانی که تابعی حداقل دو یا بیشتر آرگومان داشته باشد، می‌توان استفاده از options object را مد ِ نظر قرار داد. برای تابعی که چهار یا بیشتر آرگومان دارد، استفاده از options object معمولاً ایده‌ی خوبی است.

اگر تابعی فعلا یک آرگومان بیشتر ندارد، اما حدس می‌زنید که بعدا نیاز خواهد شد تا آرگومان‌های بیشتری به آن اضافه کنید، از همان ابتدا از options object استفاده کنید تا نیاز نباشد بعدا کد‌های خود را از نو بنویسید.

در نهایت آنچه که تعیین کننده‌ی این است که آیا options object گزینه‌ی بهتری است یا لیست آرگومان‌ها (یعنی همان روش ِ معمول برای ِ دادن ِ ورودی به توابع)، این است که آیا پاسخ به پرسش ِ «آرگومان‌ها برای چه هستند» واضح است یا نه. برای مثال ورودی‌های تابع (sum(4, 2 به قدر  ِ کافی گویا هستند، اما چیزی مثل (showDialog(true , false خیر.

نوشتن ِ یک تابع که ورودی ِ آن یک options object است

در زیر یک تابع را مشاهده می‌کنید که به روش ِ سنتی ِ گرفتن ِ آرگومان‌ها به صورتِ جدا جدا، نوشته شده است:

function showDialog (showAlertIcon, showBackdrop) {
    if (showAlertIcon) {
        alertIcon.show();
    }
    if (showDarkBackdrop) {
        backdrop.show();
    }
    dialog.show();
}

و در ادامه نحوه‌ی فراخوانی ِ آن:

showDialog(true, false);

خط ِ بالا به وضوح مشخص نمی‌کند که هر آرگومان برای چه کاری است. این مشکل با از نو نوشتن ِ تابع، به صورتی که یک options object را به عنوان ِ ورودی بگیرد، حل می‌شود:

function showDialog (options) {
    if (options.showAlertIcon) {
        alertIcon.show();
    }
    if (options.showDarkBackdrop) {
        backdrop.show();
    }
    dialog.show();
}

حال، showDialog می‌تواند با یک شیء به عنوان ِ ورودی فراخوانی شود؛ که در آن شیء به ازای ِ هر پارامتر، یک جفت ِ کلید/مقدار (به انگلیسی: key/value) وجود دارد:

showDialog({
    showAlertIcon: true,
    showDarkBackdrop: false
});

با این روش، به روشنی مشخص است که هر پارامتر ِ تابع برای چه کاری است و نیازی به نگاه انداختن به تعریف ِ تابع، برای ِ درک ِ نحوه‌ی ِ فراخوانی ِ تابع نیست.

تنظیم مقادیر اولیه

options objectها همچنین امکان ِ اختیاری کردن ِ یک پارامتر را به راحتی می‌دهند. زمانیکه یک پارامتر ِ اختیاری، مقداردهی نشده، یک مقدار ِ اولیه باید جای ِ آن را بگیرد.

کتابخانه‌ی Underscore متدی با نام ِ defaults._ دارد که options object داده شده را مستقیما تغییر می‌دهد؛ بنابراین بهتر است برای ِ عدم ِ پیش‌آمدن ِ نتایج ناخواسته، از استفاده از این متد به طور ِ مستقیم خودداری کنید.

به جای ِ آن می‌توانید یک تابع ِ مخصوص ِ خودتان بنویسید:

function setDefaults(options, defaults){
    return _.defaults({}, _.clone(options), defaults);
}

تابع ِ setDefaults یک کپی از آرگومان ِ options که به آن داده شده، می‌سازد؛ که با این کار تضمین می‌کند که options object اصلی بدون ِ تغییر خواهد‌ماند.

حالا می‌توانید از setDefaults برای ِ مقداری‌دهی ِ اولیه‌ی پارامتر ِ داده شده به تابعتان استفاده‌کنید.

  function showDialog (options) {
      var defaults = {
          showAlertIcon: false,
          showDarkBackdrop: true
      };
      options = setDefaults(options, defaults);
      if (options.showAlertIcon) {
          alertIcon.show();
      }
      if (options.showDarkBackdrop) {
          backdrop.show();
      }
      dialog.show();
  }

بعد از این تغییر می‌توانید تابع ِ showDialog را تنها با پارامتر‌هایی که می‌خواهید صدابزنید:

  showDialog({showDarkBackdrop: false});

 

منبع: http://www.codereadability.com/what-are-javascript-options-objects/

جاوااسکریپت: بررسی ِ این که آیا یک متغیر تعریف شده است یا نه

در جاوااسکریپت یک متغیر تعریف شده است «اگر و فقط اگر» حین ِ دسترسی به آن خطای ِ ReferenceError تولید نشود.

راه ِ معمولی که خیلی‌ها برای ِ بررسی ِ تعریف شده بودن ِ یک متغیر استفاده می‌کنن، به شکل ِ زیر است:

typeof variableName !== 'undefined'

عبارت ِ بولین ِ بالا در دو حالت مقدار ِ false خواهد داشت:

  • متغیر ِ مورد ِ نظر در scope وجود نداشته باشد
  • متغیر ِ مورد ِ نظر وجود داشته باشد و مقدار آن undefined باشد

در غیر ِ این صورت عبارت، مقدار ِ true را برمی‌گرداند.

اما راه ِ مطمئن، درست و البته کمی پردردسر ِ این مشکل، این است که تلاش کنیم تا به متغیر دسترسی پیدا کنیم و سپس اگر خطای ِ RefrenceError تولید شد، آن را catch کنیم و از این طریق بفهمیم که متغیر تعریف شده یا نه:

var barIsDeclared = true; 
try { bar; }
catch (e) {
    if (e.name === "ReferenceError") {
        barIsDeclared = false;
    }
}

منبع: https://stackoverflow.com/questions/16719277/checking-if-a-variable-exists-in-javascript

جاوا‌اسکریپت: بررسی وجود یک ویژگی در شئ

برای این کار سه روش معمول وجود داره که به ترتیب اونارو بررسی می‌کنیم:

روش خسته: استفاده از خاصیت undefined

انجام این کار به لطف یک رفتار خاص و البته جالب جاوا‌اسکریپت خیلی راحت انجام می‌شه: اگه یک ویژگی در شیئ موجود نباشه، مقدار undefined برای اون بر‌می‌گرده. مثلا:

const objA = {
  propA: 'A property!',
  propB: 'B property!',
};

console.log(typeof objA.propA); // prints 'string'
console.log(typeof objA.propC); // prints 'undefined'


function fA (obj) {
  // هست propFooBar اگه شیئ دارای ویژگی
  if (obj.propFooBar === undefined) // Or: typeof obj.propFooBar === 'undefined'
    console.log(obj.propFooBar);
  else
    console.log('Object does not have propFooBar');
}

fA({propSilly: "I am silly!"}); // prints 'Object does not have propFooBar'
fA({propFooBar: "I am here!"}); // prints 'I am here!'

از اونجا که در جاوا‌اسکریپت undefined وقتی به یک مقدار بولین (Boolean) تبدیل میشه معادل false میشه، شاید بعضیا تصور کنن به جای استفاده از اپراتور typeof یا مقایسه با undefined می‌تونن این کار رو انجام بدن:

const objA = {};
const objB = {propFooBar: false};

function fA (obj) {
  if (obj.propFooBar)
    console.log('Object has propFooBar');
  else
    console.log('Object does not have propFoobar');
}

/*
 * هردوی دستورات زیر خروجی دوم رو چاپ می‌کنن
 * رو ندارن propFooBar یعنی تابع فکر می‌کنه هردوی این اشیاء ویژگی 
 * در صورتی‌که شئ دوم این ویژگی رو داره
 */
fA(objA);
fA(objB);

اما این کار اشتباهه چون اگه حتی propFooBar در شئ تعریف شده باشه و مثلا مقدارش false یا null باشه بازهم به این تعبیر می‌شه که این ویژگی تعریف نشده و می‌تونه برنامه رو با خطا مواجه کنه.

حالا چرا گفتیم این ویژگی خاصه؟ چون در اکثر زبان‌ها (مثل پایتون)، وقتی می‌خوایم به یک ویژگی از شئ که اون ویژگی موجود نیست، دسترسی پیدا کنیم، با خطا مواجه می‌شیم. یعنی برای بررسی وجود یک ویژگی در شئ باید یک بلوک try…catch بنویسیم یا از توابع و امکانات خاصی که در اون زبان وجود داره استفاده کنیم (مثلا در پایتون میشه از تابع hasattr استفاده کرد). اما توجه کنید که این ویژگی در جاوا‌اسکریپت یه چاقوی دو لبس و اگه حواسمون نباشه می‌تونه آسیب بزنه!

روش دوم: استفاده از hasOwnProperty

بیاین شیئ زیر رو در نظر بگیریم:

const objC = {
  propA: undefined,
};

در objC ویژگی propA تعریف شده ولی صریحا مقدار undefined به اون داده شده! احتمالا می‌تونید حدس بزنید که اگه بخوایم با استفاده از روش قبلی بررسی کنیم که آیا این شئ ویژگی propA رو داره یا نه به اشتباه فکر خواهیم کرد که این ویژگی روی شئ تعریف نشده، در صورتیکه اینطور نیست! پس باید چیکار کرد؟ باید دست به دامن ابزار‌های خاصی شد که جاوا‌اسکریپت برامون فراهم کرده. ادامه مطلب