هش رشتهای از کاراکترها با طول ثابت است که خروجی فانکشن هش محسوب میشود. ورودی فانکشن هش میتواند طول نامحدود داشته باشد اما خروجی فانکشن هش، همیشه طول ثابت دارد.
فانکشن یا تابع هش هم یک سری عملیات ریاضی یا عملیات حساب است. طرز کار آن نیز به این شکل است که یک سری دیتا یا جریان دیتا را میگیرد و آنها را با دستورالعملهای خاصی ترکیب میکند.
بازی بیلیارد را تصور کنید. شما یکی از توپها را برمیدارید و یک ضربه بسیار محکم به آن میزنید، به طوری که توپ ۱۰۰ بار به لبههای میز برخورد کند. در نهایت این توپ در یک جای مشخصی میایستد.
اگر شما به همان توپ، در همان مکان، با همان قدرت و با همان زاویه ضربه بزنید، توپ پس از ۱۰۰ بار برخورد با لبههای میز، دقیقا در همان جای قبلی میایستد. اما اگر از مکان نهایی توپ عکس بگیرید و بعد به دنبال جای اولیه توپ بگردید، غیرممکن است بتوانید آن را پیدا کنید؛ چون ممکن است توپ حرکت خود را از زوایای مختلفی شروع کرده باشد و معنی آن این است که تقریبا بینهایت جایگاه و زوایای بسیار زیادی برای ضریه زدن وجود دارد، اما تعداد بسیار محدودی نقطه پایان وجود دارد که توپ میتواند بایستد.
توابع هش بسیار شبیه به مثال بالا کار میکنند. این توابع تقریبا اطلاعات را فشرده میکنند که این برای ایجاد ارتباط بین تابع هش و رمزنگاری سودمند است.
در حقیقت، توابع هش بسیار شبیه به رمزنگاری هستند؛ با این تفاوت که رمزنگاری قابلیت معکوس شدن دارد اما توابع هش این ویژگی را ندارند و به صورت یکطرفه کار میکند. به این معنی که اگر هش را به عنوان ورودی تابع بدهیم، نباید انتظار داشته باشیم رشتهی اصلی ورودی را دریافت کنیم.
همچنین توابع هش قابلیت فشردهسازی دارند. به این معنی که مهم نیست شما چه مقدار دیتا به تابع هش مثلا SHA256 بدهید؛ دیتای خروجی آن همیشه 256 بیت خواهد بود.
به عنوان مثال:
Input(Message): Hello
Output(Hash): 185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969
اگر حرف H را به h تغییر دهیم هش حاصل متفاوت از حالت قبل خواهد بود:
Input(Message): hello
Output(Hash): 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
این ویژگی باعث شده تا خرابکارانی که قصد تغییر در پیام ما را دارند نتوانند به هدف خود برسند. چرا که با اعمال کوچکترین تغییر در پیام اصلی هش آن تغییر میکند و گیرندهی پیام از آنجا که دو هش متفاوت از هم دارد، متوجه چنین خرابکاریایی میشود.
این نکته رو هم اضافه کنم که مهمترین کاربرد هش توی بلاکچین توی بحث محاسبه نانس هست:
وظیفهی ماینرها برای ماین کردن کوینهایی که از این الگوریتم استفاده میکنند این است که عددی را حدس بزنند (نانس nonce) که با قرار دادن آن در هش بلاک، به شرط تایید آن برسند. برای مثال “عدد حدس زده شده باید ۵ صفر داشته باشد.” هر ماینری که زودتر این عدد را پیدا کند، پاداش دریافت میکند و بلاک به بلاکچین اضافه میشود.
اینجا میتونید اطلاعات بیشتر در مورد نانس بدست بیارید:
https://twitter.com/AliMotlagh_/status/1653492527402569734?s=20
از لحاظ فنی؛ الگوریتم SHA256 از دستورالعملهای خاصی برای ترکیب کردن بیتها استفاده میکند که این عملیات در سطوح مختلف باینری انجام میگیرد؛ مانند جابجا کردن بیتها به چپ و راست و عملیات دیگر باینری.
تمام این عملیات، یک جریان قراردادی دیتا از طول دیتاهای ورودی تولید میکند. این دیتا در این الگوریتم، 256 بیت ثابت است.
تا اینجا با هش و تابع هش آشنا شدید و اینکه تابع هش باید طوری باشد که؛
- با معکوس کردن تابع هش به دیتای اولیه نرسیم.
- تابع هش غیرقابل پیشبینی باشد؛ نتوانید پیش بینی کنید که تابع هش چه خروجیای تولید میکند.
- نتوانید عمدا و با تنظیمات خاصی برای این توابع، یک خروجی مشخص تولید کنید.
## برای این که تابع هش یک ابزار موثر رمزنگاری باشد، باید شرایط زیر را برآورده کند:
- تابع هش باید یک تابع یکطرفه باشد: به بیان دیگر اگر یک تابع هش h یک مقدار هش z را تولید کرد، پیدا کردن یک مقدار x که هش آن با z یکی شود، باید فرآیند دشواری باشد. این خاصیت باعث محافظت از پیدا کردن مقدار ورودی هش توسط هکری میشود که مقدار هش را در اختیار دارد.
- اگر یک ورودی و هش آن را در اختیار داشته باشیم، پیدا کردن یک ورودی متفاوت که همان مقدار هش را بدهد، باید دشوار باشد. به بیان دیگر اگر یک تابع هش h برای یک ورودی x، یک مقدار هش (h(x را بدهد، پیدا کردن مقدار ورودی دیگری که (h(y) = h(x شود، باید دشوار باشد. این ویژگی باعث میشود در برابر هکری که یک مقدار هش ورودی را دارد و میخواهد یک مقدار متفاوت را به عنوان مقدار ورودی اصلی جایگزین آن کند، محافظت شود.
- پیدا کردن دو ورودی متفاوت با هر طولی که منجر به یک هش مشابه شود، باید دشوار باشد. این ویژگی با عنوان «تابع هش بدون تصادم» نیز شناخته میشود. به بیان دیگر برای یک تابع هش h، پیدا کردن دو ورودی متفاوت x و y به طوری که (h(x) = h(y شود، باید دشوار باشد. چون تابع هش یک تابع فشردهساز با خروجی ثابت است، نداشتن تصادم برای آن غیرممکن است. این ویژگی تنها بیان میکند که پیدا کردن این تصادمها باید بسیار سخت باشد.