I'm writing a program for fun which generates random colours for text. (If you're curious: https://github.com/Arunscape/acat)

So, I have 3 variables $r, g$, and $b$ , each of which can be any integer $\in [0, 256)$

I figure that if I want dark text on a light background, or light text on a dark background, I should generate $r,g,b$ such that their sum is within a range, either

$r + g + b \leq 255 \quad r,g,b \in [0, 255]$ for dark text


$r + g + b \geq 255 \quad r,g,b \in [0, 255]$ for light text

Here is my thought process so far for approaches I could take:

  1. generate $r$, let's say we get $r=100$
  2. g = random_num_in_range($0, 256-r)$, let's say we get $g=100$
  3. b = random_num_in_range(0, 256-r-g), let's say we get $b=50$

In this example, I would get a dark-ish yellow colour for use with a light background However, because r is always the first number to be generated, would this algorithm have some sort of bias, or would the generated colours be random?

If this algorithm does work, can I make it more efficient? I will be generating lots of colours, so the less CPU cycles I can waste, the better.

Another approach I'm thinking I could take is, instead of generating 3 random numbers for each colour, is it possible to say, generate a number between 0 and $256^3 - 1$ and then map the number to r,g,b values. (or rather I would generate numbers in the range, $[0,0x7FFFFF]$ for dark values and $[0x800000, 0xFFFFFF]$ for lighter values.

Now that I think of it, that's kind of close to hex colour codes, except that for hex colour codes, the 2 leftmost digits are r, the 2 middle are g, and the 2 left ones are for b

Or, is there some other approach that I completely missed that's much better than what I came up with? 😄

  • $\begingroup$ Just randomize also the order of variables when choosing the random numbers to get rid of the bias. $\endgroup$ Commented Jul 16, 2020 at 3:07

1 Answer 1


Your approach will definitely bias $r$ high-it will average $127.5$ and $b$ low. A simple approach is to generate four numbers, $r,g,b$ in a fixed range and a sum to normalize to. Multiply each one by $\frac {desired sum}{actual sum}$ and you are there. Certainly you can generate one random number and split it into four bytes, however the low order bits of a random number are often much less random than the high order bits.

I would be surprised if a simple sum of $r+g+b$ got you a good split of light vs. dark colors. Note that $255$ is $\frac 13$ of the way up, not $\frac 12$.

  • $\begingroup$ just making sure I understand-- so you're saying generate 4 numbers, say r,g,b, x then multiply each by x/(r+g+b) ? $\endgroup$
    – Arunscape
    Commented Jul 16, 2020 at 3:01
  • $\begingroup$ Yes, that is correct. $\endgroup$ Commented Jul 16, 2020 at 3:01

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .