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

رشته های تصادفی در برنامه های تحت وب تقریباً استفاده های زیادی دارند. از رشته های تصادفی برای جلوگیری از هم نام شدن فایل ها یا افزایش امنیت سیستم میتوان استفاده کرد.

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

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

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

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

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

 

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

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

شاید بتوان موارد زیر را مواردی دانست که بیشترین استفاده از رشته های تصادفی دارند:

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

 

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

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

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

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

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

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

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

 

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

 

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

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

 

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

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

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

 

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

 

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

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

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

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

 

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

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

 

میتوان مقدار تصادفی به دست آمده (بین 0 و 1) را در عددی صحیح ضرب کرد تا یک عدد اعشاری بزرگتر از 1 حاصل شود.

برای مثال، برای تولید یک عدد اعشاری سه رقمی، میتوان به صورت قطعه کد زیر عمل کرد.

 

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

گاهی اوقات نیاز داریم تا یک رشته (string) را به صورت تصادفی ایجاد کنیم. برای مثال میخواهیم یک رشته تصادفی با استفاده از اعداد 0 تا 9 و حروف الفبای کوچک و بزرگ انگلیسی داشته باشیم.

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

 

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

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

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

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

 

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

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

 

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

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

 

اگر میخواهید در مورد نحوه کار با زیر رشته ها در PHP بیشتر بدانید پیشنهاد میکنیم مقاله کار با substring ها در زبان php را مطالعه کنید.

 

توجه داشته باشید که رشته ای که در این تکنیک ایجاد میکنیم، از نظر علم رمزنگاری داده ها، ایمن نیست.

اما همچنان میتوان ادعا داشت که یک رشته تقریبا تصادفی و غیر قابل پیش بینی ایجاد کرده ایم و برای مسائلی که امنیت را زیر سوال نمیبرند کاربرد خواهد داشت.

 

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

برای پاسخ به چنین مسئله ای، میتوان رشته ورودی را چندین بار به هم متصل (concatenate) کرد و سپس مقدار نهایی را بهم ریخت!

همچنین از روش های و ایده های خلاقانه دیگری نیز میتوان بهره برد.

شما چه روشی رو برای تولید یک رشته ایده آل تر پیشنهاد میدید؟ از طریق دیدگاه های مقاله در پایین، اون رو با ما به اشتراک بذارید!

 

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

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

این توابع در اصل برای هش کردن یک داده به مقداری برگشت ناپذیر است؛ که اکثرا از آنها در تصدیق هویت پیام های ارسالی (با استفاده از امضای دیجیتال) استفاده میکنیم.

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

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

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

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

 

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