Эк, все усложнили!
Понятное дело, если нужно корректно генерить строки вида "#04F" вместь "#0044FF", то да, нужно дополнительные проверки, но если достаточно получать только длинную строку, и без проверки входных данных R/G/B на соответствие диапазону 0..255, и если не обращать внимания, что функция toString() универсальная, т.е. вычисления могли бы быть быстрее, то вот простой пример:
function rgb(r,g,b) {return '#'+(0x1000000+(r<<16)+(g<<8)+b).toString(16).substring(1);}