كيفية توليد سلسلة عشوائية في Java دون فقدان الصواب؟
\n\nتخيل: أنت تكتب نظام تسجيل في موقع. تحتاج إلى إنشاء رمز مميز فريد لتأكيد البريد الإلكتروني. أو توليد كلمة مرور لمستخدم جديد. أو ببساطة إنشاء معرف قابل للقراءة لرابط. أول ما يتبادر إلى الذهن هو استخدام UUID.randomUUID()، وإزالة الشرطات والاستمتاع بالحياة.
توقف. هل تعلم أن هذا الإجراء البسيط ظاهريًا يمكن أن يتحول إلى عنق زجاجة في الأداء؟ سؤال Stack Overflow "How to generate a random alpha-numeric string" حصد آلاف المشاهدات ليس من فراغ. الشيطان، كما هو الحال دائمًا، يكمن في التفاصيل: اختيار مولد الأرقام العشوائية، الخوارزمية، التعامل مع الذاكرة. في هذه المقالة، لن نكتب الكود فقط - بل سنقوم بتحسينه إلى أقصى حد.
\n\nجهز IntelliJ IDEA. هيا بنا!
\n\n1. الطريقة الأسهل (ولكن الأبطأ): UUID
\n\nلنبدأ بالكلاسيكيات. UUID يولد قيمة 128 بت. إذا أزلنا الشرطات، نحصل على 32 حرفًا بتنسيق hex (0-9, a-f). هذه سلسلة أبجدية رقمية بالفعل، ولكن بأبجدية محدودة.
public static String generateWithUUID() {\n return UUID.randomUUID().toString().replace("-", "");\n}\n\n\nالإيجابيات: سطر واحد من الكود. لا حاجة للتفكير.
\nالسلبيات: لا يمكن التحكم في الطول. فقط أحرف hex (16 حرفًا من الأبجدية). لكلمات المرور - ضعيفة. للرموز المميزة - مقبولة، ولكن هناك فارق بسيط.
\n\nبالمناسبة، UUID.randomUUID() يستخدم SecureRandom تحت الغطاء. هذا آمن تشفيريًا، ولكنه بطيء. إذا كنت بحاجة إلى 10,000 سلسلة في الثانية - ستخيب هذه الطريقة ظنك.
2. RandomStringUtils من Apache Commons Lang
\n\nكلاسيكيات تنتقل من مشروع إلى آخر. مكتبة commons-lang3 تقدم طريقة جاهزة:
import org.apache.commons.lang3.RandomStringUtils;\n\npublic static String generateWithCommons(int length) {\n return RandomStringUtils.randomAlphanumeric(length);\n}\n\n\nجميل؟ نعم. أداء؟ ليس جيدًا.
\nتحت الغطاء، RandomStringUtils يستخدم java.util.Random (غير آمن تشفيريًا) وينشئ العديد من الكائنات المؤقتة. لمعظم المهام سيكون كافيًا، ولكن إذا كنت تولد ملايين السلاسل - استعد لتوقفات GC.
3. طريقة مخصصة مع Random.nextInt()
\n\nلنكتب دراجتنا الخاصة. الطريقة الأكثر وضوحًا:
\n\nimport java.security.SecureRandom;\nimport java.util.Random;\n\npublic class RandomStringGenerator {\n private static final String ALPHANUMERIC = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";\n private static final int BASE = ALPHANUMERIC.length();\n private final Random random;\n\n public RandomStringGenerator() {\n this.random = new SecureRandom(); // للأمان التشفيري\n }\n\n public String generate(int length) {\n StringBuilder sb = new StringBuilder(length);\n for (int i = 0; i < length; i++) {\n sb.append(ALPHANUMERIC.charAt(random.nextInt(BASE)));\n }\n return sb.toString();\n }\n}\n\n\nما المهم هنا؟
\n- \n
- نستخدم
StringBuilderبسعة معروفة - لن يكون هناك توسعات غير ضرورية. \n SecureRandomيضمن أن المخرجات لا يمكن توقعها. للرموز المميزة - أمر لا غنى عنه. \n - الأبجدية محددة كسلسلة - 62 حرفًا (26+26+10). يمكن إضافة أحرف خاصة. \n
ولكن هناك مشكلة: SecureRandom قد يكون بطيئًا على Linux (انتظار الإنتروبيا). إذا كانت السرعة أهم من الأمان - استخدم ThreadLocalRandom.current().
4. التحسين باستخدام char[] و ThreadLocalRandom
\n\nهل تريد استخلاص أقصى أداء؟ نتخلى عن StringBuilder ونعمل مباشرة مع مصفوفة الأحرف:
import java.util.concurrent.ThreadLocalR