17
\$\begingroup\$

This blog post about generating random CSS color codes in JavaScript have multiple solutions for generating a random color in JavaScript. The shortest I can find is this:

'#'+(Math.random()*0xffffff).toString(16).slice(-6)

If you are not familiar with CSS color code read documentations here.

Can we do better? What about other languages?

\$\endgroup\$
6
  • \$\begingroup\$ Yours is broken, you're missing a + after the '#' \$\endgroup\$
    – Doorknob
    Sep 16, 2013 at 22:29
  • 1
    \$\begingroup\$ You can remove the slice by doing this #'+(Math.random()*0xffffff|0).toString(16) \$\endgroup\$
    – Griffin
    Sep 17, 2013 at 10:39
  • 1
    \$\begingroup\$ What is the "0xffffff" needed for? I'm not seeing much of a difference in my results without it. \$\endgroup\$
    – path411
    Sep 17, 2013 at 22:18
  • 6
    \$\begingroup\$ @path411 Theoretically, Math.random().toString(16) can produce a representation with less than 6 hex-digits after the (hexa)decimal point, in which case the function would break. For example, 0.1658172607421875 becomes 0.2A73 in hex. \$\endgroup\$
    – primo
    Sep 18, 2013 at 8:51
  • \$\begingroup\$ Linked from Random color generator. \$\endgroup\$ Jan 12, 2021 at 3:01

25 Answers 25

34
\$\begingroup\$

PHP 23 bytes

#<?=md5(rand())&ÿÿÿÿÿÿ;

Where ÿ is character 255. Bitwise and will truncate the string returned from md5, which is already in hexadecimal format.

\$\endgroup\$
1
  • 8
    \$\begingroup\$ This is one of my favourite solutions on the site. \$\endgroup\$
    – Griffin
    Sep 17, 2013 at 10:08
9
\$\begingroup\$

Three character codes are valid too, so I can save some chars (4095 == 0xfff):

Ruby, 24 23 22 18

'#%03x'%rand(4095)

If I have to use a 6-char one, then:

Ruby, 28 27 26 24 20

Shaved one character off because 8**8-1 == 0xffffff

'#%06x'%rand(8**8-1)

Thanks to chron for the format string, saving 4 chars!


Cheating (with this xkcd strip in mind):

Ruby/JS/Python/Perl/lots more, 6 (or 5)

"#a83"

I assure you, I generated it randomly!

An even cheatier version:

"red"
\$\endgroup\$
3
  • \$\begingroup\$ You don't need parentheses for method calls in Ruby, right? \$\endgroup\$
    – Mohsen
    Sep 16, 2013 at 22:50
  • \$\begingroup\$ @Mohsen Yes, but Ruby gets confused and thinks I'm calling to_s on 4095 if I omit them. \$\endgroup\$
    – Doorknob
    Sep 16, 2013 at 22:51
  • \$\begingroup\$ You can get it down to 20 with a sprintf format string: '#%06x'%rand(8**8-1) \$\endgroup\$ Sep 17, 2013 at 0:04
8
\$\begingroup\$

Javascript

'#'+Math.random().toString(16).substr(2,6)

Just a little shorter at 42.

function randomColor() {
  return '#' + Math.random().toString(16).substr(2, 6);
}

for (var n = 0; n < 16*9; n++) {
  var el = document.createElement('SPAN');
  el.style.backgroundColor = randomColor();
  document.getElementById('demo').appendChild(el);
}
span { width: calc(100%/16); 
       height: calc(100vh/9);
       margin-top: -7px; 
       display: inline-block;
     }
<div id='demo'></div>

\$\endgroup\$
3
  • 1
    \$\begingroup\$ I'm not sure why this was downvoted. It works fine in every browser I've tested. +1 \$\endgroup\$
    – primo
    Sep 17, 2013 at 6:11
  • 10
    \$\begingroup\$ #'+Math.random().toString(16).slice(-6) \$\endgroup\$
    – Mohsen
    Sep 17, 2013 at 22:30
  • \$\begingroup\$ @Mohsen nice! Didn't know slice could do negatives. \$\endgroup\$
    – tristin
    Sep 18, 2013 at 1:08
5
\$\begingroup\$

Fish 79

vnnnnnnnn 
601234567;
>xxxxxxxx<
 89""""""?
 nnABCDEF:
 vv""""""-
 vvoooooo1
 >>>>>>>>^

Not the shortest solution in the world, but it was fun to code :)

It's also not a uniform distribution, but all outputs have a non-zero probability 7 and F are most likely digits.

Outputs:

python fish.py randomColor.fish
07FFF7

python fish.py randomColor.fish
07EFD7

python fish.py randomColor.fish
366F67

python fish.py randomColor.fish
977FD7

python fish.py randomColor.fish
97F7F7

python fish.py randomColor.fish
87F6FF
\$\endgroup\$
0
4
\$\begingroup\$

PowerShell, 28 24 bytes

-4 bytes thanks to @Julian!

"#{0:X6}"-f(random 16MB)

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ You can omit the -ma as it is implicit and save 4 bytes \$\endgroup\$
    – Julian
    Jun 2, 2021 at 2:55
4
\$\begingroup\$

Vyxal , 8 7 bytes

\#k66ƈṅ

Try it Online!

\#      # Push a #
    6ƈ  # Choose six...
  k6    # Hex digits
      ṅ # Appended to the #
\$\endgroup\$
2
  • \$\begingroup\$ You can outsource a byte to a flag using this method: Try it Online! \$\endgroup\$
    – Underslash
    Jul 15, 2021 at 8:45
  • \$\begingroup\$ @Underslash Nice, thanks! \$\endgroup\$
    – emanresu A
    Jul 15, 2021 at 8:52
2
\$\begingroup\$

APL (17)

'#',(⎕D,⎕A)[6?16]

Explanation:

  • 6?16: 6 random numbers from 1 to 16
  • ⎕D,⎕A: the digits (0..9) followed by the alphabet (A..Z) (but only the first 16 values are ever used, i.e. 0..F)
  • '#',: add a # to the front
\$\endgroup\$
2
  • \$\begingroup\$ 6?16 is 6 non-repeating random values though, that narrows the colorspace a bit... \$\endgroup\$
    – mniip
    Feb 17, 2014 at 15:27
  • \$\begingroup\$ @mniip Yeah, it should be ?6⍴16 instead. \$\endgroup\$
    – Adám
    Sep 27, 2021 at 0:08
2
\$\begingroup\$

Zsh, 37 bytes

<<<\#`tr -dc 0-9a-f</*/ur*m|head -c6`

Try it online!

  • </*/ur*m: input from /dev/urandom (shortened with wildcards)
  • tr -dc 0-9a-f: keep only characters in the range 0-9a-f
  • head -c6: take the first 6 characters
  • <<<#``: prepend # and print
\$\endgroup\$
0
2
\$\begingroup\$

Python 3, 44 bytes

from secrets import*
print("#"+token_hex(3))

Try it online!

Did you know this built-in python module? It was added in python 3.6 to include some random function for paswords (more informations here).

How it works ?

Basicaly, I generate a random 3-bytes long hexadecimal string ... Yeah, that's it.

Python 2, 32 31 bytes

I also have the slightly less elegant : (also works in Python3 in 34 33 bytes by adding parenthesis for the print function)

print"#%06x"%((id(0)>>16)%8**8)

Try it online!

This one uses the fact that at each execution of the code, python uses an indivdual memory address for each object. This memeory address change at each execution of the program. As the last 16 bits of this id are not random, I shifted the result before using a modulo to have the right number of bits

Thanks to pxeger for -1 bytes

\$\endgroup\$
2
  • 1
    \$\begingroup\$ You can use id(0) for -1 byte, though I'm not sure relying on ASLR alone is necessarily a valid random source. (Python doesn't "assign an id number", it uses the memory address of the object, which is assigned by the kernel, and is typically only a bit random, so it's really only suitable for seeding a PRNG) \$\endgroup\$
    – pxeger
    Jun 1, 2021 at 13:51
  • \$\begingroup\$ @pxeger I don't know if it is a valid random source, but it seems that it choose evenly a number on the wanted interval at each execution. As I saw the same trick on other problems using random, I thought I could use it here. Otherwise I have also my first solution :p \$\endgroup\$
    – Jakque
    Jun 1, 2021 at 15:09
2
\$\begingroup\$

Vyxal , 7 bytes

\#6(k6℅

Try it Online!

Explanation

\#6(k6℅
\#      Push "#"
   (    For _
  6     in range(6):
    k6    "0123456789abcdef"
      ℅   Random item

Ṫ Concatenate the stack
\$\endgroup\$
2
\$\begingroup\$

Python 3, 32 bytes

print(f"{hash('a'):x}#"[:-8:-1]) 
\$\endgroup\$
1
\$\begingroup\$

Bash (51)

od -N4 -An -tx /dev/urandom | cut -c2-7 | sed s/^/#/
\$\endgroup\$
1
\$\begingroup\$

Python 3, 53 bytes

from random import*;print(f"#{randint(0,16**6):06x}")

Try it online!

\$\endgroup\$
1
+100
\$\begingroup\$

Python 3, 50 bytes

import time
print(f"#{int(time.time()%16**6):6x}")

Try it online!

Random generation by modulo of current time saves two precious bytes

Also 0 before 06x can be omitted

\$\endgroup\$
1
  • 1
    \$\begingroup\$ using f"{i:6x} will give leading spaces instead of 0 when i is less than 6 digits long in hexadecimal. You should instead use the format f"{i:06x}. But you also can gain 1 byte by replacing 16**6 by 8**8 an 2 bytes using "%06x"%i instead using the previous f-string syntax : Try it online! \$\endgroup\$
    – Jakque
    Jun 1, 2021 at 10:13
1
\$\begingroup\$

Nim, 57 bytes

import colors,random
randomize()
echo 0xffffff.rand.Color

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Jelly, 9 bytes

6ØhX¤€”#;

Try it online!

Explanation

6ØhX¤€”#;   Main niladic link
6           6
     €      Map
    ¤       (
 Øh           "0123456789abcdef"
   X          Choose random
    ¤       )
        ;   Prepend
      ”#      "#"
\$\endgroup\$
1
\$\begingroup\$

Julia 1.0, 24 bytes

'#'repr(rand(UInt))[3:8]

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Japt -P, 11 bytes

Gö6 msG i'#

Test it

\$\endgroup\$
1
\$\begingroup\$

Java (JDK), 54 bytes

n->"#"+Long.toHexString((int)(Math.random()*0xffffff))

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Mathematica, 30 bytes

0xfff == 4095, so we can just take a random integer from 0-4095 and convert it to hexadecimal form. We save a few characters using prefix and infix notation.

RandomInteger@4095~BaseForm~16

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Ly, 29 26 bytes

'#o6['0'??'9G[p'(+,0]po,]p

Try it online!

At a high level, here's how this one works...

  1. write out #
  2. loop 6 times...
  3. each iteration, write out a random digit in 0-f range

And for people who like gory details about stacks. :)

'#o6['0'??'9G[p'(+,0]po,]p
'#o                        - push "#" on stack, print it as char
   6[                  ,]  - loop 6 times
     '0'?                  - push "0" and "?" codepoints on stack
         ?                 - pick a random number between them
          '9G              - is it greater then "9" codepoint?
             [p    0]p     - if/then, called if pick is > "9"
               '(          - push 28 on stack (Note 1)
                 +         - add 28 to random pick (Note 1)
                  ,        - decrement (Note 1)
                      o    - print top of stack as a char
                         p - clear the loop artifact from the stack

Note 1: Mapping the codepoints :-? to a-f means adding 27 to the codepoint. The shortest way to do that would be to push ' onto the stack, but the code for that (at least on TIO) '' doesn't work. So this code loads 28 (which is ( then decrements the result with , instead.

\$\endgroup\$
1
\$\begingroup\$

C (tcc), 46 43 bytes

-3 bytes, thanks @ceilingcat

main(){srand(main);printf("#%08X",rand());}

Try it online!

4 byte color codes are valid, the last byte is used as alpha.
C is weird with random numbers because of how old it is. While the code above is technically a valid answer, it does a really bad job because different compilers treat rand() differently and often use a suboptimal generator, in addition to not actually guaranteeing every possible color. Importing a better library for generation isn't exactly a good idea for Code Golf though.

\$\endgroup\$
1
0
\$\begingroup\$

Zsh (coreutils), 26 bytes

Using jot, originally in BSD Unix. Try it Online.

jot -w\#%x -r 1 0 16777216
\$\endgroup\$
0
\$\begingroup\$

Red, 18 bytes

random 255.255.255
\$\endgroup\$
2
  • 4
    \$\begingroup\$ I don't think it gives the number in hexadecimal or adds # to the front. \$\endgroup\$
    – Bubbler
    Oct 8, 2021 at 7:52
  • \$\begingroup\$ Welcome to the site. Can you provide some way to test this? As Bubbler pointed out it looks like it doesn't work. \$\endgroup\$
    – Wheat Wizard
    Oct 8, 2021 at 9:23
0
\$\begingroup\$

Python 3.8 (pre-release), 43 bytes

from os import*
print("#"+urandom(3).hex())

Try it online!

1 byte less than current top Python 3 sol by @Jakque, as I don't think that one by @Ivar Matstoms is fair

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.