La notacion hexadecimal es un formato comodo y legible para todo lo que en el fondo es un numero: colores, mascaras de bits, flags de permisos, hashes. En PostgreSQL la funcion to_hex(int) toma un entero y devuelve su representacion hex como cadena, sin prefijo 0x. Veamos escenarios practicos y como invertir la conversion.
to_hex basico
La funcion acepta un integer o bigint y devuelve text:
SELECT to_hex(255);
SELECT to_hex(4096);
SELECT to_hex(16777215);
Detalles utiles:
- El resultado siempre va en minusculas y sin ceros a la izquierda.
- No hay prefijo
0x; si lo necesitas para mostrarlo, anadelo tu mismo: '0x' || to_hex(255).
- Para numeros negativos PostgreSQL devuelve el hex en complemento a dos, no un signo menos:
to_hex(-1) da 'ffffffff' para una entrada de 32 bits.
Cuando necesitas un ancho fijo (por ejemplo, dos caracteres por byte), rellena a la izquierda con lpad:
SELECT lpad(to_hex(15), 2, '0');
Colores y mascaras de bits
Un caso clasico es montar un color hex a partir de tres canales RGB. Supongamos que la tabla de usuarios guarda el color del avatar como un entero:
SELECT id,
'#' || lpad(to_hex(theme_color), 6, '0') AS css_color
FROM users
WHERE country = 'DE';
Asi el numero 16711680 se convierte en #ff0000, rojo puro. Rellenar a seis caracteres garantiza un CSS valido incluso cuando los bytes altos son cero.
Un segundo escenario frecuente son los flags de permisos empaquetados en un solo numero con un OR bit a bit. El hex hace legibles esas mascaras:
SELECT id,
status,
to_hex(status) AS status_hex,
(status & 4) <> 0 AS is_admin
FROM orders
WHERE (status & 4) <> 0;
Depurar valores de flags
Cuando no esta claro que bits estan activos, muestra el numero en tres formas a la vez: decimal, hex y binario:
SELECT salary,
to_hex(salary::int) AS hex,
(salary::int)::bit(32) AS bits
FROM employees
WHERE dept = 'engineering';
Gotcha: to_hex solo funciona con tipos enteros. Si le pasas un numeric o un text obtienes un error; convierte la entrada de forma explicita: to_hex(salary::int). Y ojo con el signo: para bigint el complemento a dos es mas ancho, asi que to_hex(-1::bigint) devuelve 'ffffffffffffffff', no 'ffffffff'.
Invertir el hex de vuelta a numero
PostgreSQL no tiene un from_hex(int) directo, pero hay un truco limpio via el tipo bit: un prefijo x delante de un literal hex define una cadena de bits que puedes convertir a entero.
SELECT ('x' || lpad('ff', 8, '0'))::bit(32)::int;
SELECT ('x' || lpad('1000', 8, '0'))::bit(32)::int;
El lpad a ocho caracteres importa: bit(32) necesita exactamente 32 bits, es decir 8 digitos hex. Para un bigint usa bit(64) y lpad(..., 16, '0'). El ciclo completo de ida y vuelta:
SELECT ('x' || lpad(to_hex(48879), 8, '0'))::bit(32)::int;
bytea y equivalentes en MySQL
Para datos binarios (bytea) en lugar de un solo numero, usa encode y decode con el formato hex:
SELECT encode('PG'::bytea, 'hex');
SELECT decode('5047', 'hex');
encode(..., 'hex') es ideal para hashes y bytes crudos; to_hex es para numeros.
MySQL pinta otro panorama:
HEX(255) devuelve 'FF' (en mayusculas!) y funciona tanto con numeros como con cadenas.
- Para invertir,
CONV('ff', 16, 10) pasa de hex a decimal, o UNHEX('5047') para bytes.
CONV(255, 10, 16) es un cambio flexible entre dos bases cualesquiera.
SELECT HEX(255),
CONV('ff', 16, 10),
LPAD(HEX(15), 2, '0');
ClickHouse ofrece hex(255) (tambien en mayusculas) y unhex('FF') para el inverso. Cuida la capitalizacion al comparar cadenas entre motores. En resumen: to_hex para numeros, encode/decode para bytes, y el inverso via bit en PostgreSQL o CONV/UNHEX en MySQL.
La notacion hexadecimal es un formato comodo y legible para todo lo que en el fondo es un numero: colores, mascaras de bits, flags de permisos, hashes. En PostgreSQL la funcion
to_hex(int)toma un entero y devuelve su representacion hex como cadena, sin prefijo0x. Veamos escenarios practicos y como invertir la conversion.to_hex basico
La funcion acepta un
integerobiginty devuelvetext:SELECT to_hex(255); -- 'ff' SELECT to_hex(4096); -- '1000' SELECT to_hex(16777215); -- 'ffffff'Detalles utiles:
0x; si lo necesitas para mostrarlo, anadelo tu mismo:'0x' || to_hex(255).to_hex(-1)da'ffffffff'para una entrada de 32 bits.Cuando necesitas un ancho fijo (por ejemplo, dos caracteres por byte), rellena a la izquierda con
lpad:-- Always two hex digits, e.g. for a single byte channel SELECT lpad(to_hex(15), 2, '0'); -- '0f'Colores y mascaras de bits
Un caso clasico es montar un color hex a partir de tres canales RGB. Supongamos que la tabla de usuarios guarda el color del avatar como un entero:
SELECT id, '#' || lpad(to_hex(theme_color), 6, '0') AS css_color FROM users WHERE country = 'DE';Asi el numero
16711680se convierte en#ff0000, rojo puro. Rellenar a seis caracteres garantiza un CSS valido incluso cuando los bytes altos son cero.Un segundo escenario frecuente son los flags de permisos empaquetados en un solo numero con un OR bit a bit. El hex hace legibles esas mascaras:
-- 1=read, 2=write, 4=admin packed into orders.status as a bitmask SELECT id, status, to_hex(status) AS status_hex, (status & 4) <> 0 AS is_admin FROM orders WHERE (status & 4) <> 0;Depurar valores de flags
Cuando no esta claro que bits estan activos, muestra el numero en tres formas a la vez: decimal, hex y binario:
SELECT salary, to_hex(salary::int) AS hex, (salary::int)::bit(32) AS bits FROM employees WHERE dept = 'engineering';Gotcha:
to_hexsolo funciona con tipos enteros. Si le pasas unnumerico untextobtienes un error; convierte la entrada de forma explicita:to_hex(salary::int). Y ojo con el signo: parabigintel complemento a dos es mas ancho, asi queto_hex(-1::bigint)devuelve'ffffffffffffffff', no'ffffffff'.Invertir el hex de vuelta a numero
PostgreSQL no tiene un
from_hex(int)directo, pero hay un truco limpio via el tipobit: un prefijoxdelante de un literal hex define una cadena de bits que puedes convertir a entero.-- Parse hex text back into an integer SELECT ('x' || lpad('ff', 8, '0'))::bit(32)::int; -- 255 SELECT ('x' || lpad('1000', 8, '0'))::bit(32)::int; -- 4096El
lpada ocho caracteres importa:bit(32)necesita exactamente 32 bits, es decir 8 digitos hex. Para unbigintusabit(64)ylpad(..., 16, '0'). El ciclo completo de ida y vuelta:-- Round trip: int -> hex -> int SELECT ('x' || lpad(to_hex(48879), 8, '0'))::bit(32)::int; -- 48879bytea y equivalentes en MySQL
Para datos binarios (
bytea) en lugar de un solo numero, usaencodeydecodecon el formatohex:-- Bytes to hex text and back SELECT encode('PG'::bytea, 'hex'); -- '5047' SELECT decode('5047', 'hex'); -- bytea \x5047encode(..., 'hex')es ideal para hashes y bytes crudos;to_hexes para numeros.MySQL pinta otro panorama:
HEX(255)devuelve'FF'(en mayusculas!) y funciona tanto con numeros como con cadenas.CONV('ff', 16, 10)pasa de hex a decimal, oUNHEX('5047')para bytes.CONV(255, 10, 16)es un cambio flexible entre dos bases cualesquiera.-- MySQL flavor SELECT HEX(255), -- 'FF' CONV('ff', 16, 10),-- '255' LPAD(HEX(15), 2, '0'); -- '0F'ClickHouse ofrece
hex(255)(tambien en mayusculas) yunhex('FF')para el inverso. Cuida la capitalizacion al comparar cadenas entre motores. En resumen:to_hexpara numeros,encode/decodepara bytes, y el inverso viabiten PostgreSQL oCONV/UNHEXen MySQL.