Random Six Character Strings Without Collisions












3














I want to generate a random list of six characters that only contain characters from "0...9" and "A...Z".



For this I can define



ToCharacterCode[{"ABCDEFGHIJKLMONPQRSTUVWXYZ", "0123456789"}]


I can modify the answer here as



rndnew = FromCharacterCode@
RandomChoice[Join @@ Range[{48, 65}, {57, 90}], #] &


I can now generate five of these strings by doing



rndnew[{5, 6}]


This results in something like



{"35UVUS", "F7WIJG", "PQSBHF", "PIHTSW", "R3MDM6"}


My question is how can I guarantee that these strings have no collisions (I know this is a very large space)? Is there a better way to code this using random over the range of the size of this set (like a linear congruential generator with that range) to make sure the strings are unique or is there a facility in Mathematica to do that?










share|improve this question


















  • 5




    replace RandomChoice with RandomSample?
    – kglr
    Dec 13 '18 at 14:20










  • @kglr: I will certainly look into that. Thanks for the pointer!
    – Moo
    Dec 13 '18 at 14:21






  • 2




    When a function is close to what you want, look at the See Also section of that function's documentation.
    – Bob Hanlon
    Dec 13 '18 at 14:39










  • Sorry that I'm not a Mathematica user, so just provide my thought on solving this in pseudo code: while less than 5 strings in the collection: generate a random string if new string already exists in the collection: do nothing else: add it to the collection No collisions guaranteed, but might take a while.
    – Kyle R.
    Dec 14 '18 at 0:41
















3














I want to generate a random list of six characters that only contain characters from "0...9" and "A...Z".



For this I can define



ToCharacterCode[{"ABCDEFGHIJKLMONPQRSTUVWXYZ", "0123456789"}]


I can modify the answer here as



rndnew = FromCharacterCode@
RandomChoice[Join @@ Range[{48, 65}, {57, 90}], #] &


I can now generate five of these strings by doing



rndnew[{5, 6}]


This results in something like



{"35UVUS", "F7WIJG", "PQSBHF", "PIHTSW", "R3MDM6"}


My question is how can I guarantee that these strings have no collisions (I know this is a very large space)? Is there a better way to code this using random over the range of the size of this set (like a linear congruential generator with that range) to make sure the strings are unique or is there a facility in Mathematica to do that?










share|improve this question


















  • 5




    replace RandomChoice with RandomSample?
    – kglr
    Dec 13 '18 at 14:20










  • @kglr: I will certainly look into that. Thanks for the pointer!
    – Moo
    Dec 13 '18 at 14:21






  • 2




    When a function is close to what you want, look at the See Also section of that function's documentation.
    – Bob Hanlon
    Dec 13 '18 at 14:39










  • Sorry that I'm not a Mathematica user, so just provide my thought on solving this in pseudo code: while less than 5 strings in the collection: generate a random string if new string already exists in the collection: do nothing else: add it to the collection No collisions guaranteed, but might take a while.
    – Kyle R.
    Dec 14 '18 at 0:41














3












3








3







I want to generate a random list of six characters that only contain characters from "0...9" and "A...Z".



For this I can define



ToCharacterCode[{"ABCDEFGHIJKLMONPQRSTUVWXYZ", "0123456789"}]


I can modify the answer here as



rndnew = FromCharacterCode@
RandomChoice[Join @@ Range[{48, 65}, {57, 90}], #] &


I can now generate five of these strings by doing



rndnew[{5, 6}]


This results in something like



{"35UVUS", "F7WIJG", "PQSBHF", "PIHTSW", "R3MDM6"}


My question is how can I guarantee that these strings have no collisions (I know this is a very large space)? Is there a better way to code this using random over the range of the size of this set (like a linear congruential generator with that range) to make sure the strings are unique or is there a facility in Mathematica to do that?










share|improve this question













I want to generate a random list of six characters that only contain characters from "0...9" and "A...Z".



For this I can define



ToCharacterCode[{"ABCDEFGHIJKLMONPQRSTUVWXYZ", "0123456789"}]


I can modify the answer here as



rndnew = FromCharacterCode@
RandomChoice[Join @@ Range[{48, 65}, {57, 90}], #] &


I can now generate five of these strings by doing



rndnew[{5, 6}]


This results in something like



{"35UVUS", "F7WIJG", "PQSBHF", "PIHTSW", "R3MDM6"}


My question is how can I guarantee that these strings have no collisions (I know this is a very large space)? Is there a better way to code this using random over the range of the size of this set (like a linear congruential generator with that range) to make sure the strings are unique or is there a facility in Mathematica to do that?







list-manipulation random






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Dec 13 '18 at 14:17









Moo

7011515




7011515








  • 5




    replace RandomChoice with RandomSample?
    – kglr
    Dec 13 '18 at 14:20










  • @kglr: I will certainly look into that. Thanks for the pointer!
    – Moo
    Dec 13 '18 at 14:21






  • 2




    When a function is close to what you want, look at the See Also section of that function's documentation.
    – Bob Hanlon
    Dec 13 '18 at 14:39










  • Sorry that I'm not a Mathematica user, so just provide my thought on solving this in pseudo code: while less than 5 strings in the collection: generate a random string if new string already exists in the collection: do nothing else: add it to the collection No collisions guaranteed, but might take a while.
    – Kyle R.
    Dec 14 '18 at 0:41














  • 5




    replace RandomChoice with RandomSample?
    – kglr
    Dec 13 '18 at 14:20










  • @kglr: I will certainly look into that. Thanks for the pointer!
    – Moo
    Dec 13 '18 at 14:21






  • 2




    When a function is close to what you want, look at the See Also section of that function's documentation.
    – Bob Hanlon
    Dec 13 '18 at 14:39










  • Sorry that I'm not a Mathematica user, so just provide my thought on solving this in pseudo code: while less than 5 strings in the collection: generate a random string if new string already exists in the collection: do nothing else: add it to the collection No collisions guaranteed, but might take a while.
    – Kyle R.
    Dec 14 '18 at 0:41








5




5




replace RandomChoice with RandomSample?
– kglr
Dec 13 '18 at 14:20




replace RandomChoice with RandomSample?
– kglr
Dec 13 '18 at 14:20












@kglr: I will certainly look into that. Thanks for the pointer!
– Moo
Dec 13 '18 at 14:21




@kglr: I will certainly look into that. Thanks for the pointer!
– Moo
Dec 13 '18 at 14:21




2




2




When a function is close to what you want, look at the See Also section of that function's documentation.
– Bob Hanlon
Dec 13 '18 at 14:39




When a function is close to what you want, look at the See Also section of that function's documentation.
– Bob Hanlon
Dec 13 '18 at 14:39












Sorry that I'm not a Mathematica user, so just provide my thought on solving this in pseudo code: while less than 5 strings in the collection: generate a random string if new string already exists in the collection: do nothing else: add it to the collection No collisions guaranteed, but might take a while.
– Kyle R.
Dec 14 '18 at 0:41




Sorry that I'm not a Mathematica user, so just provide my thought on solving this in pseudo code: while less than 5 strings in the collection: generate a random string if new string already exists in the collection: do nothing else: add it to the collection No collisions guaranteed, but might take a while.
– Kyle R.
Dec 14 '18 at 0:41










4 Answers
4






active

oldest

votes


















6














Just changing RandomChoice to RandomSample doesn't help, since RandomSample just means that none of the characters are repeated, and clearly you want to allow repeated characters, since one of your strings is "35UVUS". One idea is to oversample and remove duplicates. For example:



SeedRandom[1]
Take[
DeleteDuplicates[rndnew[{10, 6}]],
UpTo[5]
]



{"K1263G", "SXVXHC", "UO2PBL", "EC1FTJ", "0TKLEH"}




Another possibility is to index the possible random strings, and then do a random sample from the possible indices. For your case, the number of possible strings is simply 36^6. To convert from an index to a string:



characters = Join[CharacterRange["A","Z"], CharacterRange["0","9"]];

fromIndex[index_, len_] := StringJoin[
characters[[1+IntegerDigits[index, 36, len]]]
]


Then, a function that returns n samples of length len strings:



sample[n_, len_] := fromIndex[#, len]& /@ RandomSample[1 ;; 36^len, n]


Example:



SeedRandom[1]
sample[5, 6]



{"0621O7", "0WH6XW", "ODLV4Z", "KWSN6U", "AMOSFA"}







share|improve this answer























  • Is there a way to generate some number of these, keep the state of the RNG and use it to reseed from that point moving forward so we can maintain uniqueness of all six-characters over time?
    – Moo
    Dec 13 '18 at 16:18










  • @Moo Not that I'm aware of. Do you know how many unique strings you want in total?
    – Carl Woll
    Dec 13 '18 at 16:49










  • If I am doing my math correctly, we have 6-character strings where strings can repeat, then there are $26$ letters plus $10$ digits in the pool of characters, giving us $36$ in all per character. This means we would have $36^6 = 2176782336$ combinations.
    – Moo
    Dec 13 '18 at 16:52






  • 1




    @Moo There are 36^6 total strings, but how many do you want to generate? There is no point in using a random approach if you want to generate all of them.
    – Carl Woll
    Dec 13 '18 at 17:04










  • CarlWoll: The issue is that I would generate something like $10000$ at a time, use them and then generate a new batch and over time, duplicates matter. Maybe there is a better way based on that, but I haven't thought about it. I am not sure I would ever use up the total number shown, but it can certainly be over several million of them over time.
    – Moo
    Dec 13 '18 at 17:22





















3














RandomSample[
Union[CharacterRange["a", "z"], CharacterRange["0", "9"]], 6]


or



RandomSample[Flatten[CharacterRange @@@ {{"a", "z"}, {"0", "9"}}], 6]


or



RandomSample[Join @@ (CharacterRange @@@ {{"a", "z"}, {"0", "9"}}), 6]


This guarantees no collisions because RandomSample selects elements without replacement.






share|improve this answer























  • How does does guarantee no collisions?
    – Moo
    Dec 13 '18 at 15:31



















3














Inspired by some of the other answers and comments, here's a rather silly brute-force approach. We can RandomSample a range that we can use to enumerate all combinations.



range = Range[0, 36^6 - 1];
(* This takes a little while: 15 seconds on my laptop. *)

chars = Union[CharacterRange["a", "z"], CharacterRange["0", "9"]];

makeString[n_] := ToString@Part[chars, 1 + IntegerDigits[n, 36, 6]];


Then



makeString /@ RandomSample[range, 1000]


will always return a bunch of unique strings.






share|improve this answer

















  • 2




    This becomes much less silly if you use RandomSample[0 ;; 36^6 - 1, 1000] instead. This way, the humongous list range need not be created and 1000 words are created within 4 ms. See also Carl's answer.
    – Henrik Schumacher
    Dec 13 '18 at 21:56












  • Holy cow I had no idea that worked!
    – Pillsy
    Dec 13 '18 at 23:34



















2














Following is what you want. Unfortunately it takes time to generate all possible set for n=6. But for n=5 it works. And it is guaranteed that there is no repeated element.



val = Tuples[Join @@ (CharacterRange @@@ {{"A", "Z"}, {"0", "9"}}), 5];

RandomSample[val, 5]


Much smart way is



DeleteDuplicates[
Table[RandomSample[
Join @@ (CharacterRange @@@ {{"A", "Z"}, {"0", "9"}}), 6], 5]]


It is very unlikely to generate the same element.



n = 10000;
Length@DeleteDuplicates[
Table[RandomSample[
Join @@ (CharacterRange @@@ {{"A", "Z"}, {"0", "9"}}), 6], n]] ==
n



True




But when you increase n



Table[n = 100000;
n - Length@
DeleteDuplicates[
Table[RandomSample[
Join @@ (CharacterRange @@@ {{"A", "Z"}, {"0", "9"}}), 6], n]],
10] // Max



5




This means 5 elements are repeated when we generate 100000 sample.. Of course, it might be larger than 5.






share|improve this answer























    Your Answer





    StackExchange.ifUsing("editor", function () {
    return StackExchange.using("mathjaxEditing", function () {
    StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
    StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["$", "$"], ["\\(","\\)"]]);
    });
    });
    }, "mathjax-editing");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "387"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmathematica.stackexchange.com%2fquestions%2f187829%2frandom-six-character-strings-without-collisions%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    4 Answers
    4






    active

    oldest

    votes








    4 Answers
    4






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    6














    Just changing RandomChoice to RandomSample doesn't help, since RandomSample just means that none of the characters are repeated, and clearly you want to allow repeated characters, since one of your strings is "35UVUS". One idea is to oversample and remove duplicates. For example:



    SeedRandom[1]
    Take[
    DeleteDuplicates[rndnew[{10, 6}]],
    UpTo[5]
    ]



    {"K1263G", "SXVXHC", "UO2PBL", "EC1FTJ", "0TKLEH"}




    Another possibility is to index the possible random strings, and then do a random sample from the possible indices. For your case, the number of possible strings is simply 36^6. To convert from an index to a string:



    characters = Join[CharacterRange["A","Z"], CharacterRange["0","9"]];

    fromIndex[index_, len_] := StringJoin[
    characters[[1+IntegerDigits[index, 36, len]]]
    ]


    Then, a function that returns n samples of length len strings:



    sample[n_, len_] := fromIndex[#, len]& /@ RandomSample[1 ;; 36^len, n]


    Example:



    SeedRandom[1]
    sample[5, 6]



    {"0621O7", "0WH6XW", "ODLV4Z", "KWSN6U", "AMOSFA"}







    share|improve this answer























    • Is there a way to generate some number of these, keep the state of the RNG and use it to reseed from that point moving forward so we can maintain uniqueness of all six-characters over time?
      – Moo
      Dec 13 '18 at 16:18










    • @Moo Not that I'm aware of. Do you know how many unique strings you want in total?
      – Carl Woll
      Dec 13 '18 at 16:49










    • If I am doing my math correctly, we have 6-character strings where strings can repeat, then there are $26$ letters plus $10$ digits in the pool of characters, giving us $36$ in all per character. This means we would have $36^6 = 2176782336$ combinations.
      – Moo
      Dec 13 '18 at 16:52






    • 1




      @Moo There are 36^6 total strings, but how many do you want to generate? There is no point in using a random approach if you want to generate all of them.
      – Carl Woll
      Dec 13 '18 at 17:04










    • CarlWoll: The issue is that I would generate something like $10000$ at a time, use them and then generate a new batch and over time, duplicates matter. Maybe there is a better way based on that, but I haven't thought about it. I am not sure I would ever use up the total number shown, but it can certainly be over several million of them over time.
      – Moo
      Dec 13 '18 at 17:22


















    6














    Just changing RandomChoice to RandomSample doesn't help, since RandomSample just means that none of the characters are repeated, and clearly you want to allow repeated characters, since one of your strings is "35UVUS". One idea is to oversample and remove duplicates. For example:



    SeedRandom[1]
    Take[
    DeleteDuplicates[rndnew[{10, 6}]],
    UpTo[5]
    ]



    {"K1263G", "SXVXHC", "UO2PBL", "EC1FTJ", "0TKLEH"}




    Another possibility is to index the possible random strings, and then do a random sample from the possible indices. For your case, the number of possible strings is simply 36^6. To convert from an index to a string:



    characters = Join[CharacterRange["A","Z"], CharacterRange["0","9"]];

    fromIndex[index_, len_] := StringJoin[
    characters[[1+IntegerDigits[index, 36, len]]]
    ]


    Then, a function that returns n samples of length len strings:



    sample[n_, len_] := fromIndex[#, len]& /@ RandomSample[1 ;; 36^len, n]


    Example:



    SeedRandom[1]
    sample[5, 6]



    {"0621O7", "0WH6XW", "ODLV4Z", "KWSN6U", "AMOSFA"}







    share|improve this answer























    • Is there a way to generate some number of these, keep the state of the RNG and use it to reseed from that point moving forward so we can maintain uniqueness of all six-characters over time?
      – Moo
      Dec 13 '18 at 16:18










    • @Moo Not that I'm aware of. Do you know how many unique strings you want in total?
      – Carl Woll
      Dec 13 '18 at 16:49










    • If I am doing my math correctly, we have 6-character strings where strings can repeat, then there are $26$ letters plus $10$ digits in the pool of characters, giving us $36$ in all per character. This means we would have $36^6 = 2176782336$ combinations.
      – Moo
      Dec 13 '18 at 16:52






    • 1




      @Moo There are 36^6 total strings, but how many do you want to generate? There is no point in using a random approach if you want to generate all of them.
      – Carl Woll
      Dec 13 '18 at 17:04










    • CarlWoll: The issue is that I would generate something like $10000$ at a time, use them and then generate a new batch and over time, duplicates matter. Maybe there is a better way based on that, but I haven't thought about it. I am not sure I would ever use up the total number shown, but it can certainly be over several million of them over time.
      – Moo
      Dec 13 '18 at 17:22
















    6












    6








    6






    Just changing RandomChoice to RandomSample doesn't help, since RandomSample just means that none of the characters are repeated, and clearly you want to allow repeated characters, since one of your strings is "35UVUS". One idea is to oversample and remove duplicates. For example:



    SeedRandom[1]
    Take[
    DeleteDuplicates[rndnew[{10, 6}]],
    UpTo[5]
    ]



    {"K1263G", "SXVXHC", "UO2PBL", "EC1FTJ", "0TKLEH"}




    Another possibility is to index the possible random strings, and then do a random sample from the possible indices. For your case, the number of possible strings is simply 36^6. To convert from an index to a string:



    characters = Join[CharacterRange["A","Z"], CharacterRange["0","9"]];

    fromIndex[index_, len_] := StringJoin[
    characters[[1+IntegerDigits[index, 36, len]]]
    ]


    Then, a function that returns n samples of length len strings:



    sample[n_, len_] := fromIndex[#, len]& /@ RandomSample[1 ;; 36^len, n]


    Example:



    SeedRandom[1]
    sample[5, 6]



    {"0621O7", "0WH6XW", "ODLV4Z", "KWSN6U", "AMOSFA"}







    share|improve this answer














    Just changing RandomChoice to RandomSample doesn't help, since RandomSample just means that none of the characters are repeated, and clearly you want to allow repeated characters, since one of your strings is "35UVUS". One idea is to oversample and remove duplicates. For example:



    SeedRandom[1]
    Take[
    DeleteDuplicates[rndnew[{10, 6}]],
    UpTo[5]
    ]



    {"K1263G", "SXVXHC", "UO2PBL", "EC1FTJ", "0TKLEH"}




    Another possibility is to index the possible random strings, and then do a random sample from the possible indices. For your case, the number of possible strings is simply 36^6. To convert from an index to a string:



    characters = Join[CharacterRange["A","Z"], CharacterRange["0","9"]];

    fromIndex[index_, len_] := StringJoin[
    characters[[1+IntegerDigits[index, 36, len]]]
    ]


    Then, a function that returns n samples of length len strings:



    sample[n_, len_] := fromIndex[#, len]& /@ RandomSample[1 ;; 36^len, n]


    Example:



    SeedRandom[1]
    sample[5, 6]



    {"0621O7", "0WH6XW", "ODLV4Z", "KWSN6U", "AMOSFA"}








    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Dec 13 '18 at 16:47

























    answered Dec 13 '18 at 16:15









    Carl Woll

    67.1k388175




    67.1k388175












    • Is there a way to generate some number of these, keep the state of the RNG and use it to reseed from that point moving forward so we can maintain uniqueness of all six-characters over time?
      – Moo
      Dec 13 '18 at 16:18










    • @Moo Not that I'm aware of. Do you know how many unique strings you want in total?
      – Carl Woll
      Dec 13 '18 at 16:49










    • If I am doing my math correctly, we have 6-character strings where strings can repeat, then there are $26$ letters plus $10$ digits in the pool of characters, giving us $36$ in all per character. This means we would have $36^6 = 2176782336$ combinations.
      – Moo
      Dec 13 '18 at 16:52






    • 1




      @Moo There are 36^6 total strings, but how many do you want to generate? There is no point in using a random approach if you want to generate all of them.
      – Carl Woll
      Dec 13 '18 at 17:04










    • CarlWoll: The issue is that I would generate something like $10000$ at a time, use them and then generate a new batch and over time, duplicates matter. Maybe there is a better way based on that, but I haven't thought about it. I am not sure I would ever use up the total number shown, but it can certainly be over several million of them over time.
      – Moo
      Dec 13 '18 at 17:22




















    • Is there a way to generate some number of these, keep the state of the RNG and use it to reseed from that point moving forward so we can maintain uniqueness of all six-characters over time?
      – Moo
      Dec 13 '18 at 16:18










    • @Moo Not that I'm aware of. Do you know how many unique strings you want in total?
      – Carl Woll
      Dec 13 '18 at 16:49










    • If I am doing my math correctly, we have 6-character strings where strings can repeat, then there are $26$ letters plus $10$ digits in the pool of characters, giving us $36$ in all per character. This means we would have $36^6 = 2176782336$ combinations.
      – Moo
      Dec 13 '18 at 16:52






    • 1




      @Moo There are 36^6 total strings, but how many do you want to generate? There is no point in using a random approach if you want to generate all of them.
      – Carl Woll
      Dec 13 '18 at 17:04










    • CarlWoll: The issue is that I would generate something like $10000$ at a time, use them and then generate a new batch and over time, duplicates matter. Maybe there is a better way based on that, but I haven't thought about it. I am not sure I would ever use up the total number shown, but it can certainly be over several million of them over time.
      – Moo
      Dec 13 '18 at 17:22


















    Is there a way to generate some number of these, keep the state of the RNG and use it to reseed from that point moving forward so we can maintain uniqueness of all six-characters over time?
    – Moo
    Dec 13 '18 at 16:18




    Is there a way to generate some number of these, keep the state of the RNG and use it to reseed from that point moving forward so we can maintain uniqueness of all six-characters over time?
    – Moo
    Dec 13 '18 at 16:18












    @Moo Not that I'm aware of. Do you know how many unique strings you want in total?
    – Carl Woll
    Dec 13 '18 at 16:49




    @Moo Not that I'm aware of. Do you know how many unique strings you want in total?
    – Carl Woll
    Dec 13 '18 at 16:49












    If I am doing my math correctly, we have 6-character strings where strings can repeat, then there are $26$ letters plus $10$ digits in the pool of characters, giving us $36$ in all per character. This means we would have $36^6 = 2176782336$ combinations.
    – Moo
    Dec 13 '18 at 16:52




    If I am doing my math correctly, we have 6-character strings where strings can repeat, then there are $26$ letters plus $10$ digits in the pool of characters, giving us $36$ in all per character. This means we would have $36^6 = 2176782336$ combinations.
    – Moo
    Dec 13 '18 at 16:52




    1




    1




    @Moo There are 36^6 total strings, but how many do you want to generate? There is no point in using a random approach if you want to generate all of them.
    – Carl Woll
    Dec 13 '18 at 17:04




    @Moo There are 36^6 total strings, but how many do you want to generate? There is no point in using a random approach if you want to generate all of them.
    – Carl Woll
    Dec 13 '18 at 17:04












    CarlWoll: The issue is that I would generate something like $10000$ at a time, use them and then generate a new batch and over time, duplicates matter. Maybe there is a better way based on that, but I haven't thought about it. I am not sure I would ever use up the total number shown, but it can certainly be over several million of them over time.
    – Moo
    Dec 13 '18 at 17:22






    CarlWoll: The issue is that I would generate something like $10000$ at a time, use them and then generate a new batch and over time, duplicates matter. Maybe there is a better way based on that, but I haven't thought about it. I am not sure I would ever use up the total number shown, but it can certainly be over several million of them over time.
    – Moo
    Dec 13 '18 at 17:22













    3














    RandomSample[
    Union[CharacterRange["a", "z"], CharacterRange["0", "9"]], 6]


    or



    RandomSample[Flatten[CharacterRange @@@ {{"a", "z"}, {"0", "9"}}], 6]


    or



    RandomSample[Join @@ (CharacterRange @@@ {{"a", "z"}, {"0", "9"}}), 6]


    This guarantees no collisions because RandomSample selects elements without replacement.






    share|improve this answer























    • How does does guarantee no collisions?
      – Moo
      Dec 13 '18 at 15:31
















    3














    RandomSample[
    Union[CharacterRange["a", "z"], CharacterRange["0", "9"]], 6]


    or



    RandomSample[Flatten[CharacterRange @@@ {{"a", "z"}, {"0", "9"}}], 6]


    or



    RandomSample[Join @@ (CharacterRange @@@ {{"a", "z"}, {"0", "9"}}), 6]


    This guarantees no collisions because RandomSample selects elements without replacement.






    share|improve this answer























    • How does does guarantee no collisions?
      – Moo
      Dec 13 '18 at 15:31














    3












    3








    3






    RandomSample[
    Union[CharacterRange["a", "z"], CharacterRange["0", "9"]], 6]


    or



    RandomSample[Flatten[CharacterRange @@@ {{"a", "z"}, {"0", "9"}}], 6]


    or



    RandomSample[Join @@ (CharacterRange @@@ {{"a", "z"}, {"0", "9"}}), 6]


    This guarantees no collisions because RandomSample selects elements without replacement.






    share|improve this answer














    RandomSample[
    Union[CharacterRange["a", "z"], CharacterRange["0", "9"]], 6]


    or



    RandomSample[Flatten[CharacterRange @@@ {{"a", "z"}, {"0", "9"}}], 6]


    or



    RandomSample[Join @@ (CharacterRange @@@ {{"a", "z"}, {"0", "9"}}), 6]


    This guarantees no collisions because RandomSample selects elements without replacement.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Dec 13 '18 at 15:44

























    answered Dec 13 '18 at 15:29









    David G. Stork

    23.3k22051




    23.3k22051












    • How does does guarantee no collisions?
      – Moo
      Dec 13 '18 at 15:31


















    • How does does guarantee no collisions?
      – Moo
      Dec 13 '18 at 15:31
















    How does does guarantee no collisions?
    – Moo
    Dec 13 '18 at 15:31




    How does does guarantee no collisions?
    – Moo
    Dec 13 '18 at 15:31











    3














    Inspired by some of the other answers and comments, here's a rather silly brute-force approach. We can RandomSample a range that we can use to enumerate all combinations.



    range = Range[0, 36^6 - 1];
    (* This takes a little while: 15 seconds on my laptop. *)

    chars = Union[CharacterRange["a", "z"], CharacterRange["0", "9"]];

    makeString[n_] := ToString@Part[chars, 1 + IntegerDigits[n, 36, 6]];


    Then



    makeString /@ RandomSample[range, 1000]


    will always return a bunch of unique strings.






    share|improve this answer

















    • 2




      This becomes much less silly if you use RandomSample[0 ;; 36^6 - 1, 1000] instead. This way, the humongous list range need not be created and 1000 words are created within 4 ms. See also Carl's answer.
      – Henrik Schumacher
      Dec 13 '18 at 21:56












    • Holy cow I had no idea that worked!
      – Pillsy
      Dec 13 '18 at 23:34
















    3














    Inspired by some of the other answers and comments, here's a rather silly brute-force approach. We can RandomSample a range that we can use to enumerate all combinations.



    range = Range[0, 36^6 - 1];
    (* This takes a little while: 15 seconds on my laptop. *)

    chars = Union[CharacterRange["a", "z"], CharacterRange["0", "9"]];

    makeString[n_] := ToString@Part[chars, 1 + IntegerDigits[n, 36, 6]];


    Then



    makeString /@ RandomSample[range, 1000]


    will always return a bunch of unique strings.






    share|improve this answer

















    • 2




      This becomes much less silly if you use RandomSample[0 ;; 36^6 - 1, 1000] instead. This way, the humongous list range need not be created and 1000 words are created within 4 ms. See also Carl's answer.
      – Henrik Schumacher
      Dec 13 '18 at 21:56












    • Holy cow I had no idea that worked!
      – Pillsy
      Dec 13 '18 at 23:34














    3












    3








    3






    Inspired by some of the other answers and comments, here's a rather silly brute-force approach. We can RandomSample a range that we can use to enumerate all combinations.



    range = Range[0, 36^6 - 1];
    (* This takes a little while: 15 seconds on my laptop. *)

    chars = Union[CharacterRange["a", "z"], CharacterRange["0", "9"]];

    makeString[n_] := ToString@Part[chars, 1 + IntegerDigits[n, 36, 6]];


    Then



    makeString /@ RandomSample[range, 1000]


    will always return a bunch of unique strings.






    share|improve this answer












    Inspired by some of the other answers and comments, here's a rather silly brute-force approach. We can RandomSample a range that we can use to enumerate all combinations.



    range = Range[0, 36^6 - 1];
    (* This takes a little while: 15 seconds on my laptop. *)

    chars = Union[CharacterRange["a", "z"], CharacterRange["0", "9"]];

    makeString[n_] := ToString@Part[chars, 1 + IntegerDigits[n, 36, 6]];


    Then



    makeString /@ RandomSample[range, 1000]


    will always return a bunch of unique strings.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Dec 13 '18 at 17:17









    Pillsy

    12.7k13179




    12.7k13179








    • 2




      This becomes much less silly if you use RandomSample[0 ;; 36^6 - 1, 1000] instead. This way, the humongous list range need not be created and 1000 words are created within 4 ms. See also Carl's answer.
      – Henrik Schumacher
      Dec 13 '18 at 21:56












    • Holy cow I had no idea that worked!
      – Pillsy
      Dec 13 '18 at 23:34














    • 2




      This becomes much less silly if you use RandomSample[0 ;; 36^6 - 1, 1000] instead. This way, the humongous list range need not be created and 1000 words are created within 4 ms. See also Carl's answer.
      – Henrik Schumacher
      Dec 13 '18 at 21:56












    • Holy cow I had no idea that worked!
      – Pillsy
      Dec 13 '18 at 23:34








    2




    2




    This becomes much less silly if you use RandomSample[0 ;; 36^6 - 1, 1000] instead. This way, the humongous list range need not be created and 1000 words are created within 4 ms. See also Carl's answer.
    – Henrik Schumacher
    Dec 13 '18 at 21:56






    This becomes much less silly if you use RandomSample[0 ;; 36^6 - 1, 1000] instead. This way, the humongous list range need not be created and 1000 words are created within 4 ms. See also Carl's answer.
    – Henrik Schumacher
    Dec 13 '18 at 21:56














    Holy cow I had no idea that worked!
    – Pillsy
    Dec 13 '18 at 23:34




    Holy cow I had no idea that worked!
    – Pillsy
    Dec 13 '18 at 23:34











    2














    Following is what you want. Unfortunately it takes time to generate all possible set for n=6. But for n=5 it works. And it is guaranteed that there is no repeated element.



    val = Tuples[Join @@ (CharacterRange @@@ {{"A", "Z"}, {"0", "9"}}), 5];

    RandomSample[val, 5]


    Much smart way is



    DeleteDuplicates[
    Table[RandomSample[
    Join @@ (CharacterRange @@@ {{"A", "Z"}, {"0", "9"}}), 6], 5]]


    It is very unlikely to generate the same element.



    n = 10000;
    Length@DeleteDuplicates[
    Table[RandomSample[
    Join @@ (CharacterRange @@@ {{"A", "Z"}, {"0", "9"}}), 6], n]] ==
    n



    True




    But when you increase n



    Table[n = 100000;
    n - Length@
    DeleteDuplicates[
    Table[RandomSample[
    Join @@ (CharacterRange @@@ {{"A", "Z"}, {"0", "9"}}), 6], n]],
    10] // Max



    5




    This means 5 elements are repeated when we generate 100000 sample.. Of course, it might be larger than 5.






    share|improve this answer




























      2














      Following is what you want. Unfortunately it takes time to generate all possible set for n=6. But for n=5 it works. And it is guaranteed that there is no repeated element.



      val = Tuples[Join @@ (CharacterRange @@@ {{"A", "Z"}, {"0", "9"}}), 5];

      RandomSample[val, 5]


      Much smart way is



      DeleteDuplicates[
      Table[RandomSample[
      Join @@ (CharacterRange @@@ {{"A", "Z"}, {"0", "9"}}), 6], 5]]


      It is very unlikely to generate the same element.



      n = 10000;
      Length@DeleteDuplicates[
      Table[RandomSample[
      Join @@ (CharacterRange @@@ {{"A", "Z"}, {"0", "9"}}), 6], n]] ==
      n



      True




      But when you increase n



      Table[n = 100000;
      n - Length@
      DeleteDuplicates[
      Table[RandomSample[
      Join @@ (CharacterRange @@@ {{"A", "Z"}, {"0", "9"}}), 6], n]],
      10] // Max



      5




      This means 5 elements are repeated when we generate 100000 sample.. Of course, it might be larger than 5.






      share|improve this answer


























        2












        2








        2






        Following is what you want. Unfortunately it takes time to generate all possible set for n=6. But for n=5 it works. And it is guaranteed that there is no repeated element.



        val = Tuples[Join @@ (CharacterRange @@@ {{"A", "Z"}, {"0", "9"}}), 5];

        RandomSample[val, 5]


        Much smart way is



        DeleteDuplicates[
        Table[RandomSample[
        Join @@ (CharacterRange @@@ {{"A", "Z"}, {"0", "9"}}), 6], 5]]


        It is very unlikely to generate the same element.



        n = 10000;
        Length@DeleteDuplicates[
        Table[RandomSample[
        Join @@ (CharacterRange @@@ {{"A", "Z"}, {"0", "9"}}), 6], n]] ==
        n



        True




        But when you increase n



        Table[n = 100000;
        n - Length@
        DeleteDuplicates[
        Table[RandomSample[
        Join @@ (CharacterRange @@@ {{"A", "Z"}, {"0", "9"}}), 6], n]],
        10] // Max



        5




        This means 5 elements are repeated when we generate 100000 sample.. Of course, it might be larger than 5.






        share|improve this answer














        Following is what you want. Unfortunately it takes time to generate all possible set for n=6. But for n=5 it works. And it is guaranteed that there is no repeated element.



        val = Tuples[Join @@ (CharacterRange @@@ {{"A", "Z"}, {"0", "9"}}), 5];

        RandomSample[val, 5]


        Much smart way is



        DeleteDuplicates[
        Table[RandomSample[
        Join @@ (CharacterRange @@@ {{"A", "Z"}, {"0", "9"}}), 6], 5]]


        It is very unlikely to generate the same element.



        n = 10000;
        Length@DeleteDuplicates[
        Table[RandomSample[
        Join @@ (CharacterRange @@@ {{"A", "Z"}, {"0", "9"}}), 6], n]] ==
        n



        True




        But when you increase n



        Table[n = 100000;
        n - Length@
        DeleteDuplicates[
        Table[RandomSample[
        Join @@ (CharacterRange @@@ {{"A", "Z"}, {"0", "9"}}), 6], n]],
        10] // Max



        5




        This means 5 elements are repeated when we generate 100000 sample.. Of course, it might be larger than 5.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Dec 13 '18 at 18:50

























        answered Dec 13 '18 at 17:22









        Okkes Dulgerci

        4,0851816




        4,0851816






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Mathematica Stack Exchange!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            Use MathJax to format equations. MathJax reference.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmathematica.stackexchange.com%2fquestions%2f187829%2frandom-six-character-strings-without-collisions%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            "Incorrect syntax near the keyword 'ON'. (on update cascade, on delete cascade,)

            Alcedinidae

            RAC Tourist Trophy