生成长度为N的随机字母数字字符串


30

生成具有给定长度且仅允许字母数字字符的随机字符串的最短方法是什么?

  • 随机字符串的示例:如果N = 9,则输出为 aZua7I0Lk
  • 给定的长度N可以假定始终大于0
  • 如有必要,可以将N的最大值假定为256,但是最好使用N的上限更高但仍具有快速计算时间的解决方案
  • 允许的字符:0-9,az和AZ
  • 一个字符可以在输出字符串中出现多次
  • 每个可能的字符串应具有同等的可能性(以您的语言的随机数生成器的准确性为准)

1
我们可以假设N的最大值吗?
JAD

Answers:


4

果冻,4字节

ØBṗX

在线尝试!

说明

ØBṗX
ØB     All letters (uppercase and lowercase) and digits
  ṗ    Cartesian power with {the input}
   X   Select a random possibility

笛卡尔幂基本上生成了可以由给定的一组元素形成的给定长度的所有列表。这正是我们在这里需要的。


如果涉及UTF-8字符,那真的只有4个字节吗?一个UTF-8字符可能不止一个字节...
m13r

@ m13r Jelly使用其自己的代码页,其中所有这些都是单字节字符
FlipTack

13

出租车,2577字节

Go to Post Office:w 1 l 1 r 1 l.Pickup a passenger going to The Babelfishery.Go to The Babelfishery:s 1 l 1 r.Pickup a passenger going to Sunny Skies Park.Go to Sunny Skies Park:n 1 l 1 l 1 r.[a]Go to Heisenberg's:n 1 r 1 r 3 r.Pickup a passenger going to Cyclone.Go to Go More:n 1 l 3 l 3 l.Go to Starchild Numerology:e 2 r.62 is waiting at Starchild Numerology.Pickup a passenger going to Cyclone.Go to Cyclone:e 1 l 2 r.Pickup a passenger going to What's The Difference.Pickup a passenger going to Divide and Conquer.Pickup a passenger going to Divide and Conquer.Go to Divide and Conquer:n 2 r 2 r 1 r.Pickup a passenger going to Trunkers.Go to Trunkers:e 1 r 3 r 1 l.Pickup a passenger going to Multiplication Station.Go to Cyclone:w 2 r.Pickup a passenger going to Multiplication Station.Go to Multiplication Station:s 1 l 2 r 4 l.Pickup a passenger going to What's The Difference.Go to What's The Difference:n 2 l 1 r 3 l.Pickup a passenger going to Addition Alley.Go to Starchild Numerology:e 1 r 3 l 2 r.1 is waiting at Starchild Numerology.63 is waiting at Starchild Numerology.Pickup a passenger going to Addition Alley.Pickup a passenger going to The Underground.Go to Addition Alley:e 1 l 2 r 3 r 1 r.Pickup a passenger going to Joyless Park.Go to Writer's Depot:n 1 l 1 l.ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789- is waiting at Writer's Depot.Pickup a passenger going to Chop Suey.Go to Joyless Park:n 3 r 2 r 2 l.Go to Chop Suey:w 1 r 1 r 1 l.[b]Pickup a passenger going to Narrow Path Park.Go to Narrow Path Park:n 1 l 1 r 1 l.Go to The Underground:e 1 r.Switch to plan "c" if no one is waiting.Pickup a passenger going to The Underground.Go to Fueler Up:s.Go to Chop Suey:n 3 r 1 l.Switch to plan "b".[c]Go to Joyless Park:n 1 r.Pickup a passenger going to The Underground.Go to Narrow Path Park:w 1 r 3 l.[d]Pickup a passenger going to KonKat's.Go to KonKat's:e 1 r.Pickup a passenger going to KonKat's.Go to The Underground:s.Switch to plan "e" if no one is waiting.Pickup a passenger going to The Underground.Go to Fueler Up:s.Go to Narrow Path Park:n 4 l.Switch to plan "d".[e]Go to KonKat's:n.Pickup a passenger going to Riverview Bridge.Go to Riverview Bridge:n 1 l.Go to Narrow Path Park:e 1 l 1 r.Pickup a passenger going to Post Office.Go to Post Office:e 1 r 4 r 1 l.Go to Sunny Skies Park:s 1 r 1 l 1 r.Pickup a passenger going to The Underground.Go to The Underground:n 1 r 1 r 2 r.Switch to plan "f" if no one is waiting.Pickup a passenger going to Sunny Skies Park.Go to Sunny Skies Park:n 3 l 2 l 1 l.Switch to plan "a".[f]

在线尝试!

出租车是超级不是为此而做的,但是你可以做到!我将尝试解释未高尔夫版本下的情况。

Go to Post Office: west 1st left 1st right 1st left.
Pickup a passenger going to The Babelfishery.
Go to The Babelfishery: south 1st left 1st right.
Pickup a passenger going to Sunny Skies Park.
Go to Sunny Skies Park: north 1st left 1st left 1st right.
[a]
Go to Heisenberg's: north 1st right 1st right 3rd right.
Pickup a passenger going to Cyclone.
Go to Go More: north 1st left 3rd left 3rd left.
Go to Starchild Numerology: east 2nd right.
62 is waiting at Starchild Numerology.
Pickup a passenger going to Cyclone.
Go to Cyclone: east 1st left 2nd right.
Pickup a passenger going to What's The Difference.
Pickup a passenger going to Divide and Conquer.
Pickup a passenger going to Divide and Conquer.
Go to Divide and Conquer: north 2nd right 2nd right 1st right.
Pickup a passenger going to Trunkers.
Go to Trunkers: east 1st right 3rd right 1st left.
Pickup a passenger going to Multiplication Station.
Go to Cyclone: west 2nd right.
Pickup a passenger going to Multiplication Station.
Go to Multiplication Station: south 1st left 2nd right 4th left.
Pickup a passenger going to What's The Difference.
Go to What's The Difference: north 2nd left 1st right 3rd left.
Pickup a passenger going to Addition Alley.
Go to Starchild Numerology: east 1st right 3rd left 2nd right.
1 is waiting at Starchild Numerology.
63 is waiting at Starchild Numerology.
Pickup a passenger going to Addition Alley.
Pickup a passenger going to The Underground.
Go to Addition Alley: east 1st left 2nd right 3rd right 1st right.
Pickup a passenger going to Joyless Park.
Go to Writer's Depot: north 1st left 1st left.
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789- is waiting at Writer's Depot.
Pickup a passenger going to Chop Suey.
Go to Joyless Park: north 3rd right 2nd right 2nd left.
Go to Chop Suey: west 1st right 1st right 1st left.
[b]
Pickup a passenger going to Narrow Path Park.
Go to Narrow Path Park: north 1st left 1st right 1st left.
Go to The Underground: east 1st right.
Switch to plan "c" if no one is waiting.
Pickup a passenger going to The Underground.
Go to Fueler Up: south.
Go to Chop Suey: north 3rd right 1st left.
Switch to plan "b".
[c]
Go to Joyless Park: north 1st right.
Pickup a passenger going to The Underground.
Go to Narrow Path Park: west 1st right 3rd left.
[d]
Pickup a passenger going to KonKat's.
Go to KonKat's: east 1st right.
Pickup a passenger going to KonKat's.
Go to The Underground: south.
Switch to plan "e" if no one is waiting.
Pickup a passenger going to The Underground.
Go to Fueler Up: south.
Go to Narrow Path Park: north 4th left.
Switch to plan "d".
[e]
Go to KonKat's: north.
Pickup a passenger going to Riverview Bridge.
Go to Riverview Bridge: north 1st left.
Go to Narrow Path Park: east 1st left 1st right.
Pickup a passenger going to Post Office.
Go to Post Office: east 1st right 4th right 1st left.
Go to Sunny Skies Park: south 1st right 1st left 1st right.
Pickup a passenger going to The Underground.
Go to The Underground: north 1st right 1st right 2nd right.
Switch to plan "f" if no one is waiting.
Pickup a passenger going to Sunny Skies Park.
Go to Sunny Skies Park: north 3rd left 2nd left 1st left.
Switch to plan "a".
[f]

开始:获取标准输入
将标准输入值转换为文本,将其转换为数字,然后将其粘贴到某处等待。

计划A第1部分:获取一个随机整数1-62
获取一个随机整数,然后获取62一个数字。同时复制随机整数和,62因为稍后我们将需要它们。你只能携带一下子让我们结了3名乘客randrand62。(另外62,直到我们回来会等各地。)转到鸿沟rand通过62和截断结果得到一个整数。返回以获取的另一个副本,62并将其乘以除法中的截断的整数。最后,从的第一个副本中减去乘积rand。这给我们一个0-61的数字。现在我们必须返回到拾取a 1并将其添加到结果中以获得数字1-62。是的,所有这么多的文本行都只是mod(rand(),62)+1

计划第2部分:创建一个字符数组,从中选择
包含所有有效字符的字符串,以及一个我们不需要的末尾的字符串(稍后会详细介绍)。在63我们拿起前面的比赛这个字符串的长度。将其交给Chop Suey,将其分解成单独的乘客。

方案B:移动数组,以便我们可以一个
一个地选择一个字符,然后将每个字符移到Narrow Path Park。这是唯一可用的堆栈,也是避免剩余乘客进入的唯一方法。Townsburg中的其他所有内容都是FIFO,因此我必须回过头来,在整个循环的每次迭代中清除所有乘客。这样,我可以将它们留在公园,每次都会被63个新角色推开。一开始很A可能永远也无法逃脱

计划C:准备选择角色
这实际上只是计划D中不需要的几站。重新放置出租车以进行准备。

计划d:获取所有我们的字符希望
与反转“阵列”的第一个字符开始(这是我们不希望的第63个字符),继续拿起和连接字符作为我们从结果倒计时mod功能在计划A中。一旦您达到零,下一个字符就是您想要的那个。

计划E:淹没您不想要的那些,并返回所选的那个。
“在河景桥下车的[P]冒犯者似乎总是从侧面跌落到河里...”好吧,这摆脱了那连串的失败者。去接下一个字符并将其发送到标准输出。最后,让我们检查到目前为止已经打印了多少个字符。回到Sunny Skyes,获取我们很久以前留下的stdin值。减去一,如果结果大于零,则将其发回以等待,然后从计划A重新开始。


这是图灵完整的语言吗?我从来没听说过?如果是这样,那么这可能是有史以来最长的高尔夫答案代码!
maple_shaft

4
@maple_shaft出租车很有趣,但我可以保证这不是最长的高尔夫球答案代码。有一些一元解答严重胜过它。
土司工程师(Toast)

1
@maple_shaft我做了一些挖掘。我可以在PPCG上找到的最大答案是@ Dennis♦(当然是Dennis♦)的原始答案,但该答案来自code-bowling并已被修订。code-golf我能找到的最长答案是原始的Brain-Flak提交的有关基本quine挑战的信息。它的大小为9.5 * 10 ^ 580字节。最长的电流答案,我发现是在一元黄金测试仪:1.65 * 10 ^ 56个字节。
工程师敬酒


6

果冻,5 个字节

错过了一个把戏-见ais523的4局

ØBX$€

在线尝试!

怎么样?

ØBX$€ - Main link: n
    € - for each in range(n):
   $  -   last two links as a monad:
ØB    -     "base digits" - yields list of chars "01..9AB...Zab...z"
  X   -     random choice

我不会认为UTF-8字符的长度为一个字节oO吗?
m13r

@ m13r果冻有自己的代码页-单击答案标题中的字节以查看它。
乔纳森·艾伦

5

Shell + pwgen,13个字节

pwgen -s $1 1

-s,-安全

生成完全随机且难以记忆的密码。

样品输出

%pwgen -s 10 1
2cyhLovbfT

5

爪哇8,183个 149 97 88字节

n->{for(int t;n-->0;t*=Math.random(),System.out.printf("%c",t+=t>9?t>35?61:55:48))t=62;}

在线尝试。

移植@ 2501的C答案为 -9个字节,因此请确保也对他进行投票!

旧答案,97个字节

n->{for(int t;n-->0;t*=Math.random(),System.out.printf("%c",t>9?(t<36?65:97)+t%26:48+t%10))t=62;}

在线尝试。

说明:

n->{                           // Method with integer parameter and String return-type
  for(int t;                   //  Temp integer
      n-->0                    //  Loop the input amount of times:
      ;                        //    After every iteration:
       t*=Math.random(),       //     Set `t` to a random integer in the range [0,62)
       System.out.printf("%c", //     Print as character:
         t+=                   //      The random integer, after we've added:
            t>9?               //       If the random integer is larger than 9:
             t>35?             //        If the random integer is larger than 35:
              61               //         Add 61
             :                 //        Else:
              55               //         Add 55
            :                  //       Else:
             48))              //        Add 48
    t=62;}                     //   (Re)set `t` to 62 for the random

n->{for(int t;n-->0;t*=Math.random(),System.out.printf("%c",...))t=62;}
                               // Similar as above
         t>9?                  //      If the random integer is larger than 9:
          (t<36?               //       If the random integer is smaller than 36:
            65                 //        Start with 65 ('A')
           :                   //       Else:
            97)                //        Start with 97 ('a')
               +t%26           //       And add the random integer modulo-26
         :                     //      Else:
          48                   //       Start with 48 ('0')
            +t%10)             //       And add the random integer modulo-10

4

C,60字节

r;f(n){for(;n--;)r=rand()%62,putchar(r+=r>9?r>35?61:55:48);}

看到它在这里工作

这里查看分布

假设rand() % 62产生均匀分布,它是均匀分布的。由于62通常不会平均分配RAND_MAX,因此偏差很小。


4

雪人 58字节

((}#`""*:48vn58nR|65vn91nR,aC|97vn123nR,aCAsH1AaL#aC*;bR))

在线尝试!

这是一个子程序,它以整数作为输入并返回随机字符串。

((             subroutine
  }            make b, e, g active
  #`           e = input (from +)
  ""*          store an empty string in +
  :            what follows is the block to prepend a random char to +
    48vn58nR|  generate range(48..58) and place in g (need b and e for next step)
    65vn91nR   generate range(65..91) in b
    ,aC|       move g to e, concatenate b and e, and move the result to g
    97vn123nR  generate range(97..123) in b
    ,aC        move g to e, concatenate b and e, keeping the result in b
    AsH        shuffle the array of candidate ASCII codes stored in b
    1AaL       equivalent to 0aAwR - get the first element wrapped in an array
    #aC        retrieve + and prepend the randomly generated character
    *          store back into +
  ;bR          repeat this block e times, where e has been set to the input
))             output is given via +

应该是:((}#`""*:48vn58nR|65vn91nR,aC|97vn123nR,aCAsH1AaL#aC*;bR))
2501年

@ 2501啊,你是对的。固定,谢谢。
门把手

4

PowerShell,58 54字节

-4感谢Andrei Odegov-转换为char数组而不是循环创建char数组。

-join[char[]](65..90+97..122+48..57|random -C "$args")

生成1..2+4..5 = 1,2,4,5所有可接受的字符代码范围,然后$args使用随机选择元素数量random -Count-将生成的元素循环遍历|%{}并转换为[char]s,使用[char[]]-将其转换为字符数组-然后将整个对象封装在方括号中,并将-joined在一起。

PS C:\users\sweeneyc\Desktop> .\grstr.ps1 5
oaCE5
PS C:\users\sweeneyc\Desktop> .\grstr.ps1 10
UReh6McG7D
PS C:\users\sweeneyc\Desktop> .\grstr.ps1 30
t1YrhZf5egyzqnPlWUKV3cEoIudMTs

对于输入0无效Get-Random,因为该-Count参数仅接受大于1的数字。


您可以将获得的字节数组作为单个整体强制转换为chars数组。这将有助于节省4个字节:-join[char[]](65..90+97..122+48..57|random -C "$args")
Andrei Odegov



2

Perl 5,41个字节

40个字节的代码+ -p标志。

$\.=(a..z,A..Z,0..9)[rand 62]for 1..$_}{

在线尝试!

(a..z,A..Z,0..9)创建一个包含所有字母和数字的数组,[rand 62]返回此数组的一个随机元素,该元素是append(.=)到的$\,由于-p带有的标志,该元素在末尾隐式打印}{


或者,对于相同的字节数,但使用参数而不是标准输入:

print+(a..z,A..Z,0..9)[rand 62]for 1..pop

在线尝试!


2

R,51个字节

与其他R答案的长度相同,但方法不同。

cat(sample(c(letters,LETTERS,0:9),scan(),T),sep="")

lettersLETTERS都是内置变量,分别包含所有小写和大写字母。除此之外0:9,我们还有整个字母数字字符集。


2

R,54 52 51 49字节

intToUtf8(sample(c(65:90,97:122,48:57),scan(),T))

说明:

  1. 读取输入整数nscan()
  2. 具有ASCII值的向量: c(65:90,97:122,48:57)
  3. 样本n个 ASCII值并进行替换:sample(c(65:90,97:122,48:57),scan(),T)
  4. 使用以下命令将ASCII值转换为字符串 intToUtf8

我发现了另一种长度相同的方法。
JAD

@JarkoDubbeldam好主意,这帮助我节省了两个字节
Sven Hohenstein

天哪!干得好:)
JAD

2

JavaScript(ES6),61 54 39 52 64字节

这几乎像反向高尔夫球!在字节数上大获成功,确保将使用所有三组字符的全部范围。

f=n=>n--?btoa(String.fromCharCode(Math.random()*248))[0]+f(n):""
  • 感谢Arnauld建议使用递归函数,节省了15个字节(在一个阶段)。

试试吧

f=n=>n--?btoa(String.fromCharCode(Math.random()*248))[0]+f(n):""
i.addEventListener("input",_=>o.innerText=f(+i.value))
<input id=i type=number><pre id=o>


我已经对其进行了更新,以便包括所有三个字符组,@Arnauld; 我只是想找到一个可以包含两个以上索引的索引。感谢您提出递归选项。
粗野的

我喜欢这个主意,但我想您现在正在[0-5w-z]专门生成字符。
Arnauld

我建议btoa(String.fromCharCode(Math.random()*248))[0]统一覆盖整个范围。
Arnauld

只是注意到我自己,@ Arnauld。看起来我将不得不组合两种方法(转换toString然后编码),以确保可以返回所有3组字符的全部范围。
毛茸茸的

更好,但仍然不完整:(014589ABEFIJMNQRUVYZcdghklopstwx并且不是统一的)。
Arnauld

2

爱丽丝,24字节

/w9u"Uz;r
\0.rdao"ki@/t&

在线尝试!

这种布局已经比我原来的布局(32字节)好很多,但是我确定它不是最佳的……

说明

/      Reflect to SE. Switch to Ordinal.
       The IP now bounces diagonally up and down through the code.
09     Append 0 and 9 to an (implicit) empty string to create "09".
r      Range expansion, turns the string into "0123456789".
"az"   Push this string.
r      Range expansion, turns it into the lower-case alphabet.
i      Read all input as a string.
/      Reflect to E. Switch to Cardinal.
t      Implicitly convert the input string to the integer value N it
       contains and decrement it.
&      Run the next command N-1 times.
       The IP wraps around to the first column.
\      Reflect to NE. Switch to Ordinal. (This is not a command.)
w      Push the current IP address to the return address stack N-1
       times. This starts a loop whose body will run N times.
  .      Duplicate the lower-case alphabet.
  u      Convert it to upper case.
  d      Push the concatenation of all values on the stack. This pushes
         a single string with digits, lower-case and upper-case alphabet.
  U      Random choice. Pick a character from this string uniformly at random.
  o      Print it.
  ;      Discard the upper-case alphabet, because it will be regenerated
         in the next loop iteration (and if we leave it, then upper-case
         letters will become more and more likely as the output grows).
k      As long as there is still an address on the return address stack,
       jump back to that address (i.e. to the w). Once the return address
       stack has been depleted, this does nothing and the loop is exited.
@      Terminate the program.

2

Python + exrex,81个字节

import exrex,random
lambda n:random.choice(list(exrex.generate("[A-Za-z0-9]"*n)))

2

Python 2,79 83 79字节

import random as r,string as s;lambda x:''.join(r.sample(s.printable[:62]*x,x))

+4字节(未考虑重复)

-4个字节(感谢@Rod的使用建议printable[:62]


1
不起作用,它必须包含重复项。它可以使用固定(s.letters+s.digits)*x代替s.letters+s.digits

@Rod固定,谢谢!
Wondercricket

您还可以使用`r.sample(...)`[2::5],而不是''.join(r.sample(...))保存字节(只蟒蛇2),(s.letters+s.digits)*x可以切换到s.printable[:62]*x保存4个字节

@Rod感谢您的建议。我实现了printable,无法[2::5]上班(也许我做错了吗?)
Wondercricket

您需要在列表中r.sample()加上`` 一些
Rod

1

Brachylog,14个字节

~l{Ạụ:Ạ:Ịcṛ}ᵐc

在线尝试!

说明

~l                 Create a list of length Input
  {        }ᵐ      Map on each element of that list:
   Ạụ:Ạ:Ịc           The string "A…Za…z0…9"
          ṛ          Pick a character at random
             c     Concatenate into a single string


1

批处理,175字节

@set s=0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
@for /l %%i in (1,1,%1)do @call :c
@echo %s:~62%
:c
@set/an=%random%%%62
@call set s=%s%%%s:~%n%,1%%

s在这里执行双重任务,因为它既包含字母数字列表又包含随机选择的字符。打印结果后,代码进入子程序,其结果将被忽略。


1

派克(Pyke),4个字节

~JfH

在线尝试!

~J   -   "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
  f  -  cominbations(^, length=input)
   H - random.choice(^)

这似乎不适用于大于3的任何输入,并且我不确定它可以多次生成相同的字符。
阿塔科

这不适用于大于3的输入。我在这里尝试过:pyke.catbus.co.uk
m13r

仅创建一个4个字母数字字符的字符串就需要大约1 GB的RAM。。。对于输入10的字符串,它并没有起作用。该程序崩溃了MemoryError
m13r

1

Pyth,7 11字节

O^s++rG1GUT

在线尝试

说明

O^s++rG1GUT
    +rG1G      Take the uppercase and lowercase alphabets.
   +     UT    Add it to the list [0, ..., 9].
  s            Concatenate to get a string.
 ^         Q   Get all strings of length N.
O              Choose one at random.

这仅包括小写字母和数字,不包括大写字母
蓝色

@muddyfish好收获。固定。

1

C#-121字节

void g(int n){Console.Write(Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(new Random().Next().ToString())).Substring(0,n));}

1

带有AGL的APL(Dyalog),17个字节

(⎕A,∆a,⎕D)[?⎕⍴62]

在线尝试!

(... )[... ] 索引

⎕A,∆a,⎕D 大写字母,后跟小写字母,后跟数字

使用

62 (可能的符号数

重塑

 评估输入(n

? 将每个62更改为1…62范围内的随机数

APL(APLX),17个字节

(⎕A,⎕a,⎕D)[?⎕⍴62]


1

,13字节

LaORCz.AZ.J,t

在线尝试!

说明

               a is cmdline arg; t is 10; z is lcase alphabet; AZ is ucase (implicit)
La             Do the following, a times:
  O             Output (without newline)
   RC           random choice from:
     z           Lowercase letters
      .AZ        concatenated with uppercase letters
         .J,t    concatenated with range(10) joined into a string

1

Sinclair ZX81 / Timex TS1000 / 1500 BASIC,〜63个标记化BASIC字节

 1 INPUT N
 2 IF NOT N THEN STOP
 3 FOR N=SGN PI TO N
 4 PRINT CHR$ (CODE "A"+RND*26);
 5 NEXT N

在不使用汇编程序或没有某种UDG ROM之类的情况下,ZX81中没有小写字母,并且暂时仅输出A-Z。如果输入零,则程序停止并返回直接模式。



0

堆叠,33字节

:>[alpha 10:>ALPHA,,''#`randin]"!

在线尝试!从堆栈的顶部获取输入,将输出留在堆栈的顶部。

:>[alpha 10:>ALPHA,,''#`randin]"!
:>                                  range from 0 to n-1
  [                           ]"!   on each, do:
   alpha                            push "abc...xyz"
         10:>                       push (0 1 2 ... 8 9)
             ALPHA                  push "ABC...XYZ"
                  ,,                concat twice
                    ''#`            join by nothing
                        randin      select random member in it
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.