رشته تصادفی در PHP

رشته‌های تصادفی در برنامه‌های تحت وب تقریباً استفاده‌های زیادی دارند. مثلاً می‌توانیم برای جلوگیری از هم‌نام شدن فایل‌ها و حتی افزایش امنیت سیستم در بخش‌های مختلف استفاده کرد. در این آموزش ۶ روش و ترفند جذاب برای ساخت رشته های تصادفی در PHP را با هم یاد می‌گیریم.

در حقیقت و در دنیای واقعی نمی‌توان با قطعیت تمام گفت که یک آیتم تصادفی، واقعاً تصادفی است! وقتی یک سیستم مقدار تصادفی‌ای ایجاد می‌کند، فاکتورهای مختلفی روی آن تأثیر خواهند داشت.

برای مثال وقتی یک انسان عددی تصادفی را اعلام می‌کند، احتمالاً عددی را خواهد گفت که شامل ارقام مورد علاقه‌اش یا آخرین اعداد و ارقامی است که با آن‌ها سروکار داشته است!

بعضی افراد معتقدند که به اعداد و رشته‌های تصادفی تولیدشده توسط سیسیتم‌های کامپیوتری هم نمی‌توان اطمینان کامل داشت.

به هر حال، هنگامی که یک مقدار (عددی یا الفبایی) را با استفاده از ماشین تولید می‌کنیم، باید انتظار داشته باشیم دو ویژگی اصلی در آن دیده شود:

  • تولید آن از الگوی خاصی (pattern) پیروی نکرده باشد.
  • مقدار تولید شده توسط شخص سوم (مثلاً یک فرد مهاجم به سیستم) قابل حدس نباشد.

در ادامه با هم ۶ تکنیک برای تولید اعداد و رشته‌های الفبایی تصادفی در PHP را بررسی کرده و مثال‌هایی از آن‌ها را کار می‌کنیم.

بعضی از این تکنیک‌ها از نظر رمزنگاری امنیت بسیار بالایی دارند؛ در حالی که برخی دیگر صرفاً برای تولید مقادیر تصادفی استفاده می‌شوند.

موارد زیر چند نمونه از پراستفاده‌ترین موقعیت‌هایی است که از رشته‌های تصادفی استفاده می‌کنیم.

  • نام گذاری شبه تصادفی پرونده‌ها (فایل‌ها) برای جلوگیری از هم‌نام شدن
  • ایجاد آدرس‌های URL تصادفی
  • پیشنهاد نام کاربری
  • پیشنهاد رمز عبور کاملاً تصادفی (ممکن است نتیجه امن نباشد!)

تولید اعداد تصادفی در PHP

در ابتدا پیشنهاد می‌کنم اگر در مورد رشته‌ها (stringها) اطلاعات زیادی ندارید، آموزش رشته در PHP را ببینید و سپس ادامه این آموزش را دنبال کنید تا یادگیری کامل‌تری داشته باشید.

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

تولید عدد صحیح تصادفی

برای تولید عدد های صحیح به صورت تصادفی در زبان برنامه نویسی PHP توابع مختلفی وجود دارد؛ اینجا، دو تابع rand() و mt_rand() که عملکرد نسبتاً مشابهی دارند را بررسی خواهیم کرد.

عدد تصادفی با تابع rand

تابع rand() برای ایجاد یک عدد صحیح مثبت یا منفی استفاده می‌شود. این تابع دو ورودی دارد که هر دو ورودی به صورت اختیاری هستند. در نتیجه می‌توان تابع را بدون تعیین هیچ ورودی صدا زد و یا با دادن هر دو ورودی از آن استفاده کرد. (آموزش تابع در PHP)

در صورتی که تابع rand() بدون استفاده شود، عدد خروجی عددی بین 0 و مقداری خواهد بود که توسط تابع getrandmax() در هر لحظه به صورت تصادفی ایجاد می‌شود.

<?php

echo rand();
// output: 1354913638

?>

این تابع را می‌توانیم همراه با تعریف دو ورودی به صورت rand($min, $max) استفاده کنیم. مقدار اول مشخص‌کننده مینیموم یا کمینه عدد تصادفی و ورودی دوم، مشخص‌کننده ماکزیموم یا بیشینه عدد تصادفی مورد انتظار است.

<?php

echo rand(0, 32);
// output: 19

?>

تا قبل از PHP 7.1 عملکرد این تابع از نظر سرعت اجرا بسیار کمتر از تابع دوم یعنی mt_rand() بود، اما از ورژن 7.1 این زبان، سرعت و عملکردی مشابه با تابع بعدی دارد.

یکی از نکاتی که در استفاده از این تابع بهتر است بدانیم، این است که ورودی دوم (یعنی مقدار ماکزیموم) از مقدار اول (یعنی مینیموم) می‌تواند کمتر باشد! در اینصورت تابع بدون هیچ خطایی و کاملاً صحیح اجرا شده و مقداری تصادفی بین دو عدد داده شده را تولید خواهد کرد. مثلاً قطعه کد زیر برای تولید عدد تصادفی بین منفی 50 و مثبت 10 با PHP استفاده می‌شود:

<?php

echo rand(10, -50);
// output: -40

?>

تابع mt_rand برای تولید اعداد رندوم

عملکرد این تابع مشابه تابع قبلی است؛ با این تفاوت که در صورت تعریف دو پارامتر اختیاری، حتماً باید مقدار $max از $min بزرگتر باشد.

در صورتی که آرگومان‌های ورودی را برای تابع mt_rand() تعیین نکنیم، عددی تصادفی، بین 0 و مقدار تابع mt_getrandmax() خواهد بود. این مقدارِ ماکزیموم همواره یک عددی ثابت در سیستم است.

<?php

echo mt_rand();
// output: 502470913

?>

همچنین می‌توانیم با تعریف آرگومان‌های تابع، عددی تصادفی ایجاد شده را محدود به یک محدوده خاص کنیم. فقط توجه داشته باشید که در تولید عدد تصادفی حتماً عدد دوم باید از عدد اولی بزرگتر باشد.

<?php

echo mt_rand(0, 100);
// output: 62

echo mt_rand(-100, 0);
// output: -97

?>
آموزش کار با عبارت منظم در PHP و توابع آن

آموزش کار با عبارت منظم در PHP و توابع آن

تولید عدد اعشاری تصادفی

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

برای تولید یک عدد اعشاری به صورت تصادفی، می‌توان از توابع مربوط به تولید عدد صحیح تصادفی که پیش‌تر در مورد آن‌ها بحث شد استفاده کرد.

فقط کافی است یک عدد بین صفر و یک مقدار ماکزیموم دلخواه ایجاد کرد و سپس آن را بر مقدار ماکزیموم تقسیم کرد. با این کار یک عدد اعشاری تصادفی بین 0 و 1 خواهیم داشت.

<?php

echo rand(0,100)/100;
// output: 0.36

?>

طبق محاسبات ریاضیاتی، واضح است که هر چه مقدار ماکزیموم انتخابی عدد بزرگتر یا غیر رندتری باشد، دقت اعشار (تعداد ارقام بعد از ممیز) بیشتر خواهد شد.

به جای تعریف مقدار ماکزیموم به صورت دستی، می‌توانیم از تابع mt_getrandmax() نیز استفاده کنیم.

<?php

echo rand(0,mt_getrandmax()) / mt_getrandmax();
// output: 0.47454849047332

?>

اگر بخواهیم عدد اعشاری تصادفی ما بزرگتر از بازه 0 و 1 باشد، می‌توانیم این عدد را در یک عدد صحیح بزرگ‌تر ضرب کنیم تا عدد اعشاری نهایی یک عدد بزرگ‌تر از 1 باشد.

برای مثال، در قطعه کد زیر یک عدد اعشاری سه رقمی تصادفی در PHP ایجاد کرده‌ام:

<?php

echo ( rand(0,mt_getrandmax())/mt_getrandmax() ) * 1000;
// output: 218.59444222348

?>

تولید رشته تصادفی عدد الفبایی (Alphanumeric)

نوبت به تولید رشته تصادفی در PHP رسید! فرض کنید می‌خواهیم یک رشته تصادفی شامل اعداد 0 تا 9 و حروف الفبای کوچک و بزگر انگلیسی داشته باشیم.

تکنیک‌های مختلفی برای رسیدن به این نتیجه وجود دارد که در ادامه چند مورد از پرکاربردترین آن‌ها را با شما مرور می‌کنم. شما می‌توانید بسته به نیاز خودتان از هر روشی استفاده کنید.

تولید رشته بهم ریخته (مختلط)

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

استفاده از تابع str_shuffle

تابع str_shuffle($string) در PHP یک رشته را به عنوان ورودی گرفته و تمام کاراکترهای آن را به صورت تصادفی جابجا می‌کند. خروجی آن یک رشته با همان طول اولیه اما به صورت بهم‌ریخته خواهد بود.

<?php

$string = "Hello SabzDanesh Dear Users!";
echo str_shuffle($string);
// output: nUhlo SsazaDeHsrDels ba !ree

?>

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

در صورتی که یک رشته حاوی اعداد 0 تا 9 و تمام حروف کوچک و بزرگ الفبا را به عنوان ورودی به این تابع دهیم، یک رشته شبه تصادفی در خروجی خواهیم داشت!

<?php

$myChars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
echo str_shuffle($myChars);
// output: nHgavi7uyTCKeD2fqSALp13oQhxcjR9JVlEtYbsk0IG45XBOZN6WwMPr8FdUmz

?>

کوتاه کردن رشته خروجی با تابع substr

در صورتی که بخواهیم طول رشته تصادفی کوچک‌تر از رشته کاراکترهای ما باشد، می‌توانیم با استفاده از تابع substr() در PHP یک زیر رشته از نتیجه را انتخاب کنیم.

<?php

echo substr( str_shuffle($myChars), 5, 16 );
// output: i7uyTCKeD2fqSALp

?>

در مورد کار با زیررشته‌ها در آموزش کار با substring ها در زبان php به‌طور کامل صحبت کرده‌ام. پیشنهاد می‌کنم حتماً توابعی مثل substr() را یاد بگیرید، چون واقعاً برایتان کاربردی هستند.

توجه داشته باشید که رشته‌ای که در این تکنیک ایجاد می‌کنیم، از نظر علم رمزنگاری داده‌ها ایمن نیست. البته همچنان می‌توانیم ادعا کنیم که یک رشته تقریباً تصادفی و غیرقابل پیش‌بینی ایجاد کرده‌ایم.

استفاده از این تکنیک، بسیار ساده اما در برخی کاربردها بسیار کاربردی است! اما مسئله‌ای که شاید کمی مشکل ساز باشد این است که در این خروجی از هر کاراکتر فقط یک تکرار داریم!

یک پیشنهاد خیلی ساده برای رفع چنین مشکلی، ترکیب چندباره رشته متنی اولیه (با وصف کردن یا همان concatenate کردن) و سپس ایجاد کردن رشته تصادفی با کدهای PHP است.

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

تولید رشته های هگزادسیمان تصادفی (Hexadecimal)

برای تولید رشته‌های هگزادسیمال در php می‌توان از توابع هش (Hash) نظیر md5() یا sha1() استفاده کرد. در آموزش هش در PHP در مورد اینکه هش چی هست صحبت کرده‌ام و توابع بیشتری معرفی می‌کنم.

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

این توابع یک ورودی با هر طول دلخواهی را گرفته و یک خروجی با طول ثابت به ما می‌دهند. طول خروجی تابع md5() به اندازه 32 کاراکتر و برای تابع sha1() تعداد 40 کاراکتر است.

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

یک ایده برای داشتن یک مقدار متفاوت در هر لحظه، استفاده از تابع time() است. در آموزش کار با زمان در PHP در مورد این تابع و کاربردهای آن به‌طور کامل صحبت کرده‌ام.

خروجی تابع time() یک عدد است که تعداد ثانیه‌های گذشته شده از مبدأ زمانی سیستم‌های کامپیوتری (یکم ماه اول سال 1970) است. به همین دلیل، خروجی آن در هر ثانیه یک مقدار جدید خواهد بود.

<?php

echo md5( time() );
// output: fd74b39a98e9898793de0729e02df216

echo sha1( time() );
// output: 4b6669b8540730df2d679bbc70ea5015c129170a

?>

اگر این رشته برای هدفی که دارید طولانی است، می‌توانید از تابع substr() مشابه کاری که در بالاتر انجام دادیم استفاده کنید.

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

شما چه روشی را برای تولید یک رشته ایده‌آل پیشنهاد می‌دهید؟ از بخش دیدگاه‌های انتهای مقاله، روش پیشنهادی و نظر خود را با ما و دوستانتان به اشتراک بذارید! 🙂