Python generate random color hex

Generating random color codes in Python 3

I was looking at question from Stack Overflow asking How to use random to choose colors. I wanted to take a shot at it before reading the answers again.

  • I was thinking of a 24-bit RGB color in hex representation, e.g. #ff9900 (I come from HTML and CSS)
  • But hex is just a representation/format, like octal and decimal. In decimal, a 24-bit color is a number between 0 and 16777216. ( 16**6 which means 0-F 6 times)
  • The web colors consist of red, green and blue (RGB) channels. Maybe I should return a byte for each channel instead of all at once. Maybe it matters in terms of distribution?
  • Can I do this with str.format or % formatting?

At first I made a function to return a hexadecimal string

import random def rand_web_color_hex(): rgb = "" for _ in "RGB": i = random.randrange(0, 2**8) rgb += i.to_bytes(1, "big").hex() return rgb print(rand_web_color_hex()) # 2f04d8 print(rand_web_color_hex()) # 8dbc53 print(rand_web_color_hex()) # 022632 

Then I thought I might make a function to return a decimal number, too

import random def rand_web_color_dec(): return random.randrange(0, 16**6) print(rand_web_color_dec()) # 7431420 print(rand_web_color_dec()) # 12678862 print(rand_web_color_dec()) # 582912 

Naturally, a lot smaller. A simple call to randrange() to return a 24-bit integer. Makes me want to revisit the hex function to simplify it. Hex is simply a number formatted in base16, and for web colors, they are zero-padded to maintain their length of 6 hexadecimal chars. I know there’s a way to return numbers in hex notation using str.format or % formatting.

def rand_web_color_hex(): return "%06x" % random.randrange(0, 16**6) print(rand_web_color_hex()) # 06dffd print(rand_web_color_hex()) # 6f0e2a print(rand_web_color_hex()) # 1d3df2 

In the above code, I’m using the % string formatting operator from PEP 3101, where %x will format a number user lower-case hex notation, 6 pads the string with spaces to make it consist of at least six characters, and lastly, the 0 will use zeros for padding instead of spaces.

Читайте также:  Qr код распознать php

Now, if I want to return a color with separated channels, like rgb(r, g, b) format, I must add another function. I can use bytearray.fromhex() to convert from hex to a byte array.

def rand_web_color_hex(): return "%06x" % random.randrange(0, 16**6) def to_rgb(color_str): barr = bytearray.fromhex(color_str) return (barr[0], barr[1], barr[2]) hex_color = rand_web_color_hex() print(hex_color, to_rgb(hex_color)) # 958c3b (149, 140, 59) 

Cleaning up and refactoring a bit, yields the following code.

import random def rand_24_bit(): """Returns a random 24-bit integer""" return random.randrange(0, 16**6) def color_dec(): """Alias of rand_24 bit()""" return rand_24_bit() def color_hex(num=rand_24_bit()): """Returns a 24-bit int in hex""" return "%06x" % num def color_rgb(num=rand_24_bit()): """Returns three 8-bit numbers, one for each channel in RGB""" hx = color_hex(num) barr = bytearray.fromhex(hx) return (barr[0], barr[1], barr[2]) c = color_dec() print("%8d #%6s rgb%s" % ( c, color_hex(c), color_rgb(c) )) 

This was a good exercise for maths and formatting in Python. Hope you liked it too!

Side notes

For the formatting of the decimal notation, I wanted to figure out the maximum number of digits a 24-bit number could consist of in base10. @capitol of Hackeriet helped me out with the formula. Thanks!

References

If you have any comments or feedback, please send me an e-mail. (stig at stigok dotcom).

Did you find any typos, incorrect information, or have something to add? Then please propose a change to this post.

Posts sharing categories with this post

python

Creative Commons License

This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

Источник

Python generate random color hex

Last updated: Feb 22, 2023
Reading time · 5 min

banner

# Table of Contents

# Generate a random Hex string in Python

To generate a random hex string:

  1. Use the os.urandom() method to get a byte string of N random bytes.
  2. Use the binascii.b2a_hex() method to return the hexadecimal representation of the binary data.
Copied!
import binascii import os result = binascii.b2a_hex(os.urandom(10)) print(result) # 👉️ b'a28ad94dde798a004e4d' string = result.decode('utf-8') print(string) # 👉️ a28ad94dde798a004e4d print(len(result)) # 👉️ 20

generate random hex string

The os.urandom method takes a size argument and returns a cryptographically secure byte string of size random bytes.

How the method is implemented depends on the underlying operating system.

The binascii.b2a_hex method returns the hexadecimal representation of the supplied binary data.

# Converting the bytes object to a string

You can use the bytes.decode() method if you need to convert the bytes object to a string.

Copied!
import binascii import os result = binascii.b2a_hex(os.urandom(10)) print(result) # 👉️ b'a28ad94dde798a004e4d' string = result.decode('utf-8') print(string) # 👉️ a28ad94dde798a004e4d print(len(result)) # 👉️ 20

converting bytes object to string

The bytes.decode method returns a string decoded from the given bytes. The default encoding is utf-8 .

An alternative approach is to use the random.choices() method.

# Generate a random Hex string using random.choices()

This is a two-step process:

  1. Use the random.choices() to select N digits from a sequence of hexadecimal digits.
  2. Use the str.join() method to join the N digits into a string.
Copied!
import random def gen_random_hex_string(size): return ''.join(random.choices('0123456789abcdef', k=size)) result = gen_random_hex_string(16) print(result) # 👉️ db688cb662842860

If you also need to include the capital letters A-F , you can also use the string.hexdigits attribute.

Copied!
import string # 👇️ 0123456789abcdefABCDEF print(string.hexdigits)

The random.choices method returns a k sized list of elements chosen from the provided iterable with replacement.

Copied!
import random result = random.choices('0123456789abcdef', k=10) # 👇️ ['f', '1', '0', '7', 'b', '4', 'a', '8', 'd', 'b'] print(result)

Once we have a list of hexadecimal digits, we can use the str.join() method to join the list into a string.

Copied!
import random def gen_random_hex_string(size): return ''.join(random.choices('0123456789abcdef', k=size)) result = gen_random_hex_string(16) print(result) # 👉️ e36fd2ec559d35d1

The str.join method takes an iterable as an argument and returns a string which is the concatenation of the strings in the iterable.

The string the method is called on is used as the separator between the elements.

# Generate a random Hex string using secrets.token_hex()

If you need to generate a cryptographically secure hex string, use the secrets module.

The token_hex() method from the secrets module returns a random text string in hexadecimal.

Copied!
import secrets result = secrets.token_hex(16) print(result) # 👉️ c39d47a82e4fda7cd43ca139db5cebb3 print(len(result)) # 👉️ 32

The secrets module is used for generating cryptographically strong random numbers for passwords, security tokens, etc.

The secrets.token_hex method returns a random text string in hexadecimal.

The argument the method takes is the number of random bytes the string should contain. Each byte gets converted to 2 hex digits.

# Generate a random hex color in Python

To generate a random hex color:

  1. Use the random.choices() method to select 6 random hex symbols.
  2. Use the str.join() method to join the list into a string.
  3. Use the addition (+) operator to prepend a hash symbol to the string.
Copied!
import random def gen_random_hex_color(): hex_digits = '0123456789ABCDEF' return '#' + ''.join( random.choices(hex_digits, k=6) ) print(gen_random_hex_color()) # 👉️ #6DB16C print(gen_random_hex_color()) # 👉️ #8E5D29 print(gen_random_hex_color()) # 👉️ #7593E1

We used the random.choices() method to select 6 random hex symbols.

The random.choices method returns a k sized list of elements chosen from the provided iterable with replacement.

Copied!
import random # 👇️ ['9', 'A', 'C', 'C', '2', 'C'] print(random.choices('0123456789ABCDEF', k=6))

# Use the random.choice() version in older Python versions

The random.choices() method was introduced in Python 3.9. If you use an older version, use the random.choice() method.

Copied!
import random def gen_random_hex_color(): hex_digits = '0123456789ABCDEF' return '#' + ''.join( random.choice(hex_digits) for _ in range(6) ) print(gen_random_hex_color()) # 👉️ #6F1C2B print(gen_random_hex_color()) # 👉️ #2B1364 print(gen_random_hex_color()) # 👉️ #6F8E77

The random.choice method takes a sequence and returns a random element from the non-empty sequence.

Copied!
import random print(random.choice('bobby')) # 👉️ "o"

Once we have a collection of random hex symbols, we can use the str.join() method to join the characters into a string.

The str.join method takes an iterable as an argument and returns a string which is the concatenation of the strings in the iterable.

The string the method is called on is used as the separator between the elements.

The last step is to use the addition (+) operator to prepend a hash symbol to the string.

Copied!
import random def gen_random_hex_color(): hex_digits = '0123456789ABCDEF' return '#' + ''.join( random.choices(hex_digits, k=6) ) print(gen_random_hex_color()) # 👉️ #6DB16C

Alternatively, you can use a formatted string literal.

# Generate a random hex color using a formatted string literal

This is a two-step process:

  1. Use the random.randint() method to get 3 random numbers from 0 to 255.
  2. Use a formatted string literal to format the digits in hex.
Copied!
import random def gen_random_hex_color(): def get_int(): return random.randint(0, 255) return f'#get_int():02X>get_int():02X>get_int():02X>' print(gen_random_hex_color()) # 👉️ #A5F627 print(gen_random_hex_color()) # 👉️ #671D75 print(gen_random_hex_color()) # 👉️ #B37340

The random.randint function takes 2 numbers — a and b as parameters and returns a random integer in the range.

Note that the range is inclusive — meaning both a and b can be returned.

Formatted string literals (f-strings) let us include expressions inside of a string by prefixing the string with f .

Copied!
var1 = 'bobby' var2 = 'hadz' result = f'var1>var2>' print(result) # 👉️ bobbyhadz

Make sure to wrap expressions in curly braces — .

Formatted string literals also enable us to use the format specification mini-language in expression blocks.

The :02 syntax is used to pad each value with leading zeros to a fixed width of 2.

Copied!
def gen_random_hex_color(): def get_int(): return random.randint(0, 255) return f'#get_int():02X>get_int():02X>get_int():02X>' print(gen_random_hex_color()) # 👉️ #A5F627 print(gen_random_hex_color()) # 👉️ #671D75

If the generated number is less than 10 , it gets padded to 2 digits.

The X character stands for hex format.

It outputs the number in base 16, using uppercase letters for the digits above 9 .

The last step is to add a hash symbol at the beginning of the string.

Which approach you pick is a matter of personal preference. I’d use the random.choices() method because I find it easier to read.

# Additional Resources

You can learn more about the related topics by checking out the following tutorials:

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.

Источник

Оцените статью