জাভাতে ইউআইডি স্ট্রিং উত্পন্ন করার কার্যকর পদ্ধতি (ইউএইউডি.আরেন্ডমিউইউডি ()। ট্যাশ ছাড়াই স্ট্রিং ())


154

বাইটগুলির অনন্য ক্রম উত্পন্ন করার জন্য আমি একটি দক্ষ ইউটিলিটি চাই। ইউআইডি হ'ল একজন ভাল প্রার্থী তবে UUID.randomUUID().toString()এমন স্টাফ তৈরি করে 44e128a5-ac7a-4c9a-be4c-224b6bf81b20যা ভাল but তবে আমি ড্যাশ-কম স্ট্রিং পছন্দ করব।

আমি কেবলমাত্র বর্ণানুক্রমিক অক্ষর (কোনও ড্যাশ বা অন্য কোনও বিশেষ চিহ্ন নয়) থেকে এলোমেলোভাবে স্ট্রিং উত্পন্ন করার জন্য একটি কার্যকর উপায় সন্ধান করছি।


38
এই জাতীয় ইউইউডি এইচটিটিপি-র মাধ্যমে সংক্রমণ করার জন্য ড্যাশগুলি কেন সরানো দরকার?
ব্রুনো

6
আমি ভাবিইনি যে এইচটিটিপিতে সাধারণভাবে ড্যাশগুলি অপসারণ করা দরকার ... কোন বিট আপনাকে ঝামেলা করছে?
জন স্কিটি

2
হয়তো একটি মোবাইল পরিবেশে, আপনি কি এখনও প্রতিটি বাইট জন্য টাকা দিতে যদি প্রেরিত, এবং একটি কম ব্যান্ডউইথ ও উচ্চ-লেটেন্সি নেটওয়ার্কের ব্যবহার করে, 4 বাইট সংরক্ষণ এখনও কিছু পরিস্থিতিতে গুরুত্বপূর্ণ ...
গাইডো

2
আমি ড্যাশগুলি অপসারণ করতে চাই কারণ আমরা পরে ইউআইডি স্ট্রিংটিকে অনন্য অনুরোধ সনাক্তকারী হিসাবে ব্যবহার করেছি, কেবলমাত্র হেক্স দশমিক অক্ষরের সাথে কাজ করা আরও সহজ [তারপর-এ-এফ0-9-]।
ম্যাক্সিম ভেক্সলার

আমি এইচটিটিপি অংশটি সরিয়েছি কারণ এটি প্রাসঙ্গিক নয় (যেমন ম্যাক্সিম ব্যাখ্যা করেছেন), কেবলমাত্র পাঠকদের বিভ্রান্ত করে (যেমন মন্তব্য এবং উত্তর উভয়ই দেখা যায়)।
ওন্দ্রা Žižka

উত্তর:


274

এটি এটি করে:

public static void main(String[] args) {
    final String uuid = UUID.randomUUID().toString().replace("-", "");
    System.out.println("uuid = " + uuid);
}

উদাহরণস্বরূপ, মংডোব অবজেক্টআইডি-তে ড্যাশ ব্যবহার করে না। তাই ড্যাশগুলি অপসারণ এপিআইয়ের জন্য দরকারী।
আলেক্সি রায়জস্কিখ

1
আমি একটি কারণ দেব। আমি এমন একটি এপিআই রয়েছে যার সাথে আমি কাজ করছি (উচ্চ প্রোফাইল, সুপরিচিত) যা এর ইউআইডি-তে ড্যাশগুলিকে অনুমতি দেয় না। আপনি তাদের ফালা আছে।
মাইকেল গেইনস

19
নিয়মিত এক্সপ্রেশন ব্যবহার করে এমন সমস্ত প্রতিস্থাপনের দরকার নেই। কেবলমাত্র .replace ("-", "")
ক্রেিগো

1
স্ট্রিং ক্লাসের প্রতিস্থাপনের পদ্ধতিটি কিছুটা ধীর
গতিযুক্ত

প্রথম অনুরোধের জন্য @ বিএমএসকম্প, এটি ধীর গতির, তবে পরবর্তী অনুরোধগুলির জন্য, কোনও সমস্যা নেই।
গৌরব

30

এই থ্রেডের ইউআরএল দেখতে আপনি এইচটিটিপি অনুরোধ থেকে ড্যাশগুলি সরানোর দরকার নেই don't তবে আপনি যদি ডেটার উপর নির্ভরশীলতা ছাড়াই সুসংগঠিত ইউআরএল প্রস্তুত করতে চান তবে আপনার ডাটা স্ট্যান্ডার্ড ফর্ম পরিবর্তনের পরিবর্তে আপনার ইউআরএলএনসিওডার.ইনকোড (স্ট্রিং ডেটা, স্ট্রিং এনকোডিং) ব্যবহার করা উচিত। ইউআইডি স্ট্রিংয়ের জন্য প্রতিনিধিত্বমূলক ড্যাশগুলি স্বাভাবিক।


"এই থ্রেডের ইউআরএল দেখতে আপনি এইচটিটিপি অনুরোধ থেকে ড্যাশগুলি সরানোর দরকার নেই।" বুঝতে পারবেন না, যদি না স্ট্যাক ওভারফ্লো আগে তাদের ইউআরএলগুলিতে ইউআইডি ব্যবহার না করে?
রেনিপেট

1
Url একটি http://stackoverflow.com/questions/3804591/efficient-method-to-generate-uuid-string-in-java-uuid-randomuuid-tostring-w?rq=1
ইউআইডি

12

ইউইউডি.জেভা বাস্তবায়নের উপর ভিত্তি করে আমার নিজের কিছু লিখতে শেষ হয়েছে। মনে রাখবেন যে আমি কোনও ইউইউডি তৈরি করছি না , তার পরিবর্তে কেবল র্যান্ডম 32 বাইট হেক্স স্ট্রিংটি আমি সবচেয়ে কার্যকরভাবে ভাবতে পারি।

বাস্তবায়ন

import java.security.SecureRandom;
import java.util.UUID;

public class RandomUtil {
    // Maxim: Copied from UUID implementation :)
    private static volatile SecureRandom numberGenerator = null;
    private static final long MSB = 0x8000000000000000L;

    public static String unique() {
        SecureRandom ng = numberGenerator;
        if (ng == null) {
            numberGenerator = ng = new SecureRandom();
        }

        return Long.toHexString(MSB | ng.nextLong()) + Long.toHexString(MSB | ng.nextLong());
    }       
}

ব্যবহার

RandomUtil.unique()

টেস্ট

এটি কাজ করছে তা নিশ্চিত করার জন্য আমি পরীক্ষিত কিছু ইনপুট:

public static void main(String[] args) {
    System.out.println(UUID.randomUUID().toString());
    System.out.println(RandomUtil.unique());

    System.out.println();
    System.out.println(Long.toHexString(0x8000000000000000L |21));
    System.out.println(Long.toBinaryString(0x8000000000000000L |21));
    System.out.println(Long.toHexString(Long.MAX_VALUE + 1));
}

1
কেন এটিকে আরও আপগ্রেটেড করা হচ্ছে তা নিশ্চিত নন, এখানে লিখিত সমস্ত বিকল্প থেকে সবচেয়ে কার্যকর পদ্ধতিতে "-" ছাড়াই এই ইউইউডি উত্পন্ন হয়। স্ট্রিং প্রতিস্থাপন আরও ভাল নয় তারপর দীর্ঘ থেকে স্ট্রিংতে রূপান্তর। এটি সত্য যে উভয়ই ও (এন), তবুও যেখানে আপনি এক মিনিটে কয়েক মিলিয়ন ইউইড তৈরি করেন তা অর্থবহ হয়ে ওঠে।
ম্যাক্সিম ভেক্সলার

10

আমি অনন্য আইডি উত্পন্ন করতে JUG (জাভা ইউইউডি জেনারেটর) ব্যবহার করেছি। এটি জেভিএমগুলিতে অনন্য। ব্যবহার করা বেশ ভাল। আপনার রেফারেন্সের জন্য কোডটি এখানে:

private static final SecureRandom secureRandom = new SecureRandom();
private static final UUIDGenerator generator = UUIDGenerator.getInstance();

public synchronized static String generateUniqueId() {
  UUID uuid = generator.generateRandomBasedUUID(secureRandom);

  return uuid.toString().replaceAll("-", "").toUpperCase();
}

আপনি লাইব্রেরিটি ডাউনলোড করতে পারেন: https://github.com/cowtowncoder/java-uuid-generator


আপনার ক্ষেত্রে ইউআইডি.আরন্ডম ইউইউডি ()। টু স্ট্রিং () এর সাথে কী দোষ আছে? এছাড়াও লক্ষ করুন যে আপনি (তাত্ত্বিকভাবে) একটি স্ট্যাটিক চূড়ান্ত SecureRandom (এটিকে অস্থির করে তোলেন) ধরে এনট্রপি হ্রাস করুন। এছাড়াও জেনারেট ইউনিক আইডি সিঙ্ক্রোনাইজ কেন? এর অর্থ এই পদ্ধতিতে আপনার সমস্ত থ্রেড অবরুদ্ধ।
ম্যাক্সিম ভেক্সলার

সবার আগে, সাফহাউসের দাবি JUG দ্রুত faster এবং এটি মেশিনগুলিতে অনন্য আইডি জেনারেট করতে পারে যা আপনার প্রয়োজন হতে পারে না। তাদের সময়-ভিত্তিক পদ্ধতি রয়েছে যা সমস্ত পদ্ধতির মধ্যে সর্বাধিকতম এক। হ্যাঁ, এখানে সিঙ্ক্রোনাইজ করা প্রয়োজনীয় নয় কারণ 'আমি বুঝতে পেরেছি SecureRandom ইতিমধ্যে থ্রেড নিরাপদ। সিকিউরর্যান্ডমকে স্থির চূড়ান্ত ঘোষণার ফলে এনট্রপি কমবে কেন? আমি কৌতূহলী :) এখানে আরও বিশদ রয়েছে: jug.safehaus.org/ FAQ
শেং চিয়েন

JUG এলোমেলো-সংখ্যা ভিত্তিক ইউআইডিও তৈরি করতে পারে; তবে বিকাশকারীরা সময় ভিত্তিক বৈকল্পিক ব্যবহার পছন্দ করার প্রধান কারণগুলি হ'ল এটি 10-10x দ্রুত ( কাটাটাউনকোডার / ব্লগ / আর্কাইভস / 2010/10 / entry_429.html ); অথবা তারা অনন্য আইডিগুলি উত্পাদন করার জন্য
এলোমেলোভাবে

jug.safehaus.org এর আর অস্তিত্ব নেই তবে আপনি FA.gwww.wiki.github.com/cowtowncoder/java-uuid-generator/3.0/…
ড্যানিয়েল সেরোদিও

জেউজি উল্লেখ করার জন্য +1 - এর কার্যকারিতাটি আমার কাছে পর্যালোচনা আছে তবে কিছু গুরুতর java.util.UUIDবিকল্প রয়েছে তা জেনে রাখা ভাল ।
গ্রেগ দুবিকি

8

একটি সহজ সমাধান

UUID.randomUUID().toString().replace("-", "")

(বিদ্যমান সমাধান, শুধুমাত্র এটি এড়াতে মতো স্ট্রিং # replaceAll কল। নিয়মিত প্রকাশ প্রতিস্থাপন এখানে প্রয়োজন হয় না, তাই স্ট্রিং # প্রতিস্থাপন মতানুযায়ী আরো প্রাকৃতিক, যদিও টেকনিক্যালি এটা এখনও রেগুলার এক্সপ্রেশনের সাথে বাস্তবায়িত হয়। দেওয়া হয় যে UUID প্রজন্মের প্রতিস্থাপনের চেয়ে বেশি ব্যয়বহুল, রানটাইমের ক্ষেত্রে উল্লেখযোগ্য পার্থক্য থাকা উচিত নয়))

বেশিরভাগ দৃশ্যের জন্য ইউআইডি ক্লাস ব্যবহার করা সম্ভবত যথেষ্ট দ্রুত, যদিও আমি আশা করব যে কিছু বিশেষ হাতে লিখিত বৈকল্পিক, যা পোস্টপ্রসেসিংয়ের প্রয়োজন হয় না, দ্রুত হয়। যাইহোক, সামগ্রিক গণনার মূল সমস্যাটি সাধারণত এলোমেলো সংখ্যা জেনারেটর হবে। ইউআইডি ক্লাসের ক্ষেত্রে এটি সিকিউরআরডম ব্যবহার করে

কোন এলোমেলো নম্বর জেনারেটরটি ব্যবহার করতে হবে তা অ্যাপ্লিকেশানের উপর নির্ভর করে এমন একটি বাণিজ্যও। এটি যদি সুরক্ষা-সংবেদনশীল হয় তবে সিকিউরর্যান্ডম সাধারণভাবেই সুপারিশ হয়। অন্যথায়, থ্রেডলোক্যালআরডম একটি বিকল্প (সিকিওর্যান্ডম বা পুরাতন র্যান্ডম থেকে দ্রুত তবে ক্রিপ্টোগ্রাফিকভাবে সুরক্ষিত নয়)।


7

ইউআইডির ধারণাগুলি প্রতিস্থাপন করে এতগুলি স্ট্রিং দেখে আমি অবাক হয়েছি। এটি সম্পর্কে:

UUID temp = UUID.randomUUID();
String uuidString = Long.toHexString(temp.getMostSignificantBits())
     + Long.toHexString(temp.getLeastSignificantBits());

এটি হ'ল এটি করার দ্রুততম উপায় যেহেতু ইউইউডিটির পুরো টু স্ট্রিং () ইতিমধ্যে নিয়মিত এক্সপ্রেশনটি উল্লেখ করা উচিত নয় যা পার্স এবং এক্সিকিউট করতে হবে বা খালি স্ট্রিংয়ের সাথে প্রতিস্থাপন করা উচিত।


6
এটি নির্ভরযোগ্য নয়। লিডিং বিটগুলি 0 হলে আউটপুট সংক্ষিপ্ত হবে
ওজি ডড

7
String.format("0x%016x%016x", f.getMostSignificantBits(), f.getLeastSignificantBits())
গ্যালেন্টস

@galets যদিও আমি অগ্রসর হওয়ার 0 সেঃ সঙ্গে সমস্যা সমাধানের জন্য আপনার মন্তব্যকে ভোট করেছি, আমি ভাবছি এই ব্যবহার ড্যাশ প্রতিস্থাপন বিকল্প তুলনায় কোনো ভাল হবে কিনা replace
igorcadelima


3

আমি সবেমাত্র ইউআইডি টু স্ট্রিং () পদ্ধতিটি অনুলিপি করেছি এবং এটি থেকে "-" সরাতে এটি আপডেট করেছি updated এটি অন্য যে কোনও সমাধানের চেয়ে অনেক দ্রুত এবং সোজাভাবে এগিয়ে যাবে

public String generateUUIDString(UUID uuid) {
    return (digits(uuid.getMostSignificantBits() >> 32, 8) +
            digits(uuid.getMostSignificantBits() >> 16, 4) +
            digits(uuid.getMostSignificantBits(), 4) +
            digits(uuid.getLeastSignificantBits() >> 48, 4) +
            digits(uuid.getLeastSignificantBits(), 12));
}

/** Returns val represented by the specified number of hex digits. */
private String digits(long val, int digits) {
    long hi = 1L << (digits * 4);
    return Long.toHexString(hi | (val & (hi - 1))).substring(1);
}

ব্যবহার:

generateUUIDString(UUID.randomUUID())

প্রতিবিম্ব ব্যবহার করে আরেকটি বাস্তবায়ন

public String generateString(UUID uuid) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {

    if (uuid == null) {
        return "";
    }

    Method digits = UUID.class.getDeclaredMethod("digits", long.class, int.class);
    digits.setAccessible(true);

    return ( (String) digits.invoke(uuid, uuid.getMostSignificantBits() >> 32, 8) +
            digits.invoke(uuid, uuid.getMostSignificantBits() >> 16, 4) +
            digits.invoke(uuid, uuid.getMostSignificantBits(), 4) +
            digits.invoke(uuid, uuid.getLeastSignificantBits() >> 48, 4) +
            digits.invoke(uuid, uuid.getLeastSignificantBits(), 12));

}

2

আমি একটি ইউইউডিটিকে একটি url- নিরাপদ অনন্য স্ট্রিংয়ে রূপান্তর করতে org.apache.commons.codec.binary.Base64 ব্যবহার করি যা দৈর্ঘ্যে 22 টি অক্ষর এবং ইউইউডি-র মতো একই স্বাতন্ত্র্য রয়েছে।

আমি স্ট্রিং ইউআইডি তে আমার কোড বেস 64 স্ট্রিং হিসাবে পোস্ট করেছি


0

আমি এই ইউটিলিটি ক্লাসটি বাস্তবায়িত করেছি যা ড্যাশগুলির সাথে বা ছাড়াই স্ট্রিং হিসাবে ইউআইডিগুলিকে তৈরি করে । বিনামূল্যে ব্যবহার করতে এবং ভাগ করতে পারেন। আমি আশা করি এটি সাহায্য করে!

package your.package.name;

import java.security.SecureRandom;
import java.util.Random;

/**
 * Utility class that creates random-based UUIDs.
 * 
 */
public abstract class RandomUuidStringCreator {

    private static final int RANDOM_VERSION = 4;

    /**
     * Returns a random-based UUID as String.
     * 
     * It uses a thread local {@link SecureRandom}.
     * 
     * @return a random-based UUID string
     */
    public static String getRandomUuid() {
        return getRandomUuid(SecureRandomLazyHolder.SECURE_RANDOM);
    }

    /**
     * Returns a random-based UUID as String WITH dashes.
     * 
     * It uses a thread local {@link SecureRandom}.
     * 
     * @return a random-based UUID string
     */
    public static String getRandomUuidWithDashes() {
        return format(getRandomUuid());
    }

    /**
     * Returns a random-based UUID String.
     * 
     * It uses any instance of {@link Random}.
     * 
     * @return a random-based UUID string
     */
    public static String getRandomUuid(Random random) {

        long msb = 0;
        long lsb = 0;

        // (3) set all bit randomly
        if (random instanceof SecureRandom) {
            // Faster for instances of SecureRandom
            final byte[] bytes = new byte[16];
            random.nextBytes(bytes);
            msb = toNumber(bytes, 0, 8); // first 8 bytes for MSB
            lsb = toNumber(bytes, 8, 16); // last 8 bytes for LSB
        } else {
            msb = random.nextLong(); // first 8 bytes for MSB
            lsb = random.nextLong(); // last 8 bytes for LSB
        }

        // Apply version and variant bits (required for RFC-4122 compliance)
        msb = (msb & 0xffffffffffff0fffL) | (RANDOM_VERSION & 0x0f) << 12; // apply version bits
        lsb = (lsb & 0x3fffffffffffffffL) | 0x8000000000000000L; // apply variant bits

        // Convert MSB and LSB to hexadecimal
        String msbHex = zerofill(Long.toHexString(msb), 16);
        String lsbHex = zerofill(Long.toHexString(lsb), 16);

        // Return the UUID
        return msbHex + lsbHex;
    }

    /**
     * Returns a random-based UUID as String WITH dashes.
     * 
     * It uses a thread local {@link SecureRandom}.
     * 
     * @return a random-based UUID string
     */
    public static String getRandomUuidWithDashes(Random random) {
        return format(getRandomUuid(random));
    }

    private static long toNumber(final byte[] bytes, final int start, final int length) {
        long result = 0;
        for (int i = start; i < length; i++) {
            result = (result << 8) | (bytes[i] & 0xff);
        }
        return result;
    }

    private static String zerofill(String string, int length) {
        return new String(lpad(string.toCharArray(), length, '0'));
    }

    private static char[] lpad(char[] chars, int length, char fill) {

        int delta = 0;
        int limit = 0;

        if (length > chars.length) {
            delta = length - chars.length;
            limit = length;
        } else {
            delta = 0;
            limit = chars.length;
        }

        char[] output = new char[chars.length + delta];
        for (int i = 0; i < limit; i++) {
            if (i < delta) {
                output[i] = fill;
            } else {
                output[i] = chars[i - delta];
            }
        }
        return output;
    }

    private static String format(String string) {
        char[] input = string.toCharArray();
        char[] output = new char[36];

        System.arraycopy(input, 0, output, 0, 8);
        System.arraycopy(input, 8, output, 9, 4);
        System.arraycopy(input, 12, output, 14, 4);
        System.arraycopy(input, 16, output, 19, 4);
        System.arraycopy(input, 20, output, 24, 12);

        output[8] = '-';
        output[13] = '-';
        output[18] = '-';
        output[23] = '-';

        return new String(output);
    }

    // Holds lazy secure random
    private static class SecureRandomLazyHolder {
        static final Random SECURE_RANDOM = new SecureRandom();
    }

    /**
     * For tests!
     */
    public static void main(String[] args) {

        System.out.println("// Using `java.security.SecureRandom` (DEFAULT)");
        System.out.println("RandomUuidCreator.getRandomUuid()");
        System.out.println();
        for (int i = 0; i < 5; i++) {
            System.out.println(RandomUuidStringCreator.getRandomUuid());
        }

        System.out.println();
        System.out.println("// Using `java.util.Random` (FASTER)");
        System.out.println("RandomUuidCreator.getRandomUuid(new Random())");
        System.out.println();
        Random random = new Random();
        for (int i = 0; i < 5; i++) {
            System.out.println(RandomUuidStringCreator.getRandomUuid(random));
        }
    }
}

এটি আউটপুট:

// Using `java.security.SecureRandom` (DEFAULT)
RandomUuidStringCreator.getRandomUuid()

'f553ca75657b4b5d85bedf1082785a0b'
'525ecc389e934f209b97d0f0db09d9c6'
'93ec6425bb04499ab47b790fd013ab0d'
'c2d438c620ea4cd5baafd448f9fe945b'
'fb4bc5734931415e94e78da62cb5fe0d'

// Using `java.util.Random` (FASTER)
RandomUuidStringCreator.getRandomUuid(new Random())

'051360b5c92d40fbbb89b40842adbacc'
'a993896538aa43faacbcfd83f913f38b'
'720684d22c584d5299cb03cdbc1912d2'
'82cf94ea296a4a138a92825a0068d4a1'
'a7eda46a215c4e55be3aa957ba74ca9c'
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.