A notacao hexadecimal e um formato comodo e legivel para tudo o que no fundo e um numero: cores, mascaras de bits, flags de permissao, hashes. No PostgreSQL a funcao to_hex(int) recebe um inteiro e devolve sua representacao hex como string, sem o prefixo 0x. Vamos percorrer cenarios praticos e como inverter a conversao.
to_hex basico
A funcao aceita um integer ou bigint e devolve text:
SELECT to_hex(255);
SELECT to_hex(4096);
SELECT to_hex(16777215);
Detalhes uteis:
- O resultado vem sempre em minusculas e sem zeros a esquerda.
- Nao ha prefixo
0x; se voce precisa dele para exibir, adicione-o por conta propria: '0x' || to_hex(255).
- Para numeros negativos o PostgreSQL devolve o hex em complemento de dois, nao um sinal de menos:
to_hex(-1) da 'ffffffff' para uma entrada de 32 bits.
Quando voce precisa de largura fixa (por exemplo, dois caracteres por byte), preencha a esquerda com lpad:
SELECT lpad(to_hex(15), 2, '0');
Cores e mascaras de bits
Um caso classico e montar uma cor hex a partir de tres canais RGB. Suponha que a tabela de usuarios guarda a cor do avatar como um inteiro:
SELECT id,
'#' || lpad(to_hex(theme_color), 6, '0') AS css_color
FROM users
WHERE country = 'DE';
Assim o numero 16711680 vira #ff0000, vermelho puro. Preencher ate seis caracteres garante um CSS valido mesmo quando os bytes altos sao zero.
Um segundo cenario frequente sao as flags de permissao empacotadas em um unico numero com um OR bit a bit. O hex deixa essas mascaras legiveis:
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
Quando nao esta claro quais bits estao ativos, mostre o numero em tres formas ao mesmo tempo: decimal, hex e binario:
SELECT salary,
to_hex(salary::int) AS hex,
(salary::int)::bit(32) AS bits
FROM employees
WHERE dept = 'engineering';
Gotcha: to_hex so funciona com tipos inteiros. Se voce passar um numeric ou um text, recebe um erro; converta a entrada de forma explicita: to_hex(salary::int). E atencao ao sinal: para bigint o complemento de dois e mais largo, entao to_hex(-1::bigint) devolve 'ffffffffffffffff', nao 'ffffffff'.
Inverter o hex de volta para numero
O PostgreSQL nao tem um from_hex(int) direto, mas ha um truque limpo via o tipo bit: um prefixo x na frente de um literal hex define uma cadeia de bits que voce pode converter para inteiro.
SELECT ('x' || lpad('ff', 8, '0'))::bit(32)::int;
SELECT ('x' || lpad('1000', 8, '0'))::bit(32)::int;
O lpad para oito caracteres importa: bit(32) precisa de exatamente 32 bits, ou seja 8 digitos hex. Para um bigint use bit(64) e lpad(..., 16, '0'). O ciclo completo de ida e volta:
SELECT ('x' || lpad(to_hex(48879), 8, '0'))::bit(32)::int;
bytea e equivalentes no MySQL
Para dados binarios (bytea) em vez de um unico numero, use encode e decode com o formato hex:
SELECT encode('PG'::bytea, 'hex');
SELECT decode('5047', 'hex');
encode(..., 'hex') e ideal para hashes e bytes crus; to_hex e para numeros.
O MySQL pinta outro panorama:
HEX(255) devolve 'FF' (em maiusculas!) e funciona tanto com numeros quanto com strings.
- Para inverter,
CONV('ff', 16, 10) passa de hex para decimal, ou UNHEX('5047') para bytes.
CONV(255, 10, 16) e uma troca flexivel entre quaisquer duas bases.
SELECT HEX(255),
CONV('ff', 16, 10),
LPAD(HEX(15), 2, '0');
O ClickHouse oferece hex(255) (tambem em maiusculas) e unhex('FF') para o inverso. Cuidado com a capitalizacao ao comparar strings entre motores. Resumo: to_hex para numeros, encode/decode para bytes, e o inverso via bit no PostgreSQL ou CONV/UNHEX no MySQL.
A notacao hexadecimal e um formato comodo e legivel para tudo o que no fundo e um numero: cores, mascaras de bits, flags de permissao, hashes. No PostgreSQL a funcao
to_hex(int)recebe um inteiro e devolve sua representacao hex como string, sem o prefixo0x. Vamos percorrer cenarios praticos e como inverter a conversao.to_hex basico
A funcao aceita um
integeroubiginte devolvetext:SELECT to_hex(255); -- 'ff' SELECT to_hex(4096); -- '1000' SELECT to_hex(16777215); -- 'ffffff'Detalhes uteis:
0x; se voce precisa dele para exibir, adicione-o por conta propria:'0x' || to_hex(255).to_hex(-1)da'ffffffff'para uma entrada de 32 bits.Quando voce precisa de largura fixa (por exemplo, dois caracteres por byte), preencha a esquerda com
lpad:-- Always two hex digits, e.g. for a single byte channel SELECT lpad(to_hex(15), 2, '0'); -- '0f'Cores e mascaras de bits
Um caso classico e montar uma cor hex a partir de tres canais RGB. Suponha que a tabela de usuarios guarda a cor do avatar como um inteiro:
SELECT id, '#' || lpad(to_hex(theme_color), 6, '0') AS css_color FROM users WHERE country = 'DE';Assim o numero
16711680vira#ff0000, vermelho puro. Preencher ate seis caracteres garante um CSS valido mesmo quando os bytes altos sao zero.Um segundo cenario frequente sao as flags de permissao empacotadas em um unico numero com um OR bit a bit. O hex deixa essas mascaras legiveis:
-- 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
Quando nao esta claro quais bits estao ativos, mostre o numero em tres formas ao mesmo tempo: decimal, hex e binario:
SELECT salary, to_hex(salary::int) AS hex, (salary::int)::bit(32) AS bits FROM employees WHERE dept = 'engineering';Gotcha:
to_hexso funciona com tipos inteiros. Se voce passar umnumericou umtext, recebe um erro; converta a entrada de forma explicita:to_hex(salary::int). E atencao ao sinal: parabiginto complemento de dois e mais largo, entaoto_hex(-1::bigint)devolve'ffffffffffffffff', nao'ffffffff'.Inverter o hex de volta para numero
O PostgreSQL nao tem um
from_hex(int)direto, mas ha um truque limpo via o tipobit: um prefixoxna frente de um literal hex define uma cadeia de bits que voce pode converter para inteiro.-- 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; -- 4096O
lpadpara oito caracteres importa:bit(32)precisa de exatamente 32 bits, ou seja 8 digitos hex. Para umbigintusebit(64)elpad(..., 16, '0'). O ciclo completo de ida e volta:-- Round trip: int -> hex -> int SELECT ('x' || lpad(to_hex(48879), 8, '0'))::bit(32)::int; -- 48879bytea e equivalentes no MySQL
Para dados binarios (
bytea) em vez de um unico numero, useencodeedecodecom o formatohex:-- Bytes to hex text and back SELECT encode('PG'::bytea, 'hex'); -- '5047' SELECT decode('5047', 'hex'); -- bytea \x5047encode(..., 'hex')e ideal para hashes e bytes crus;to_hexe para numeros.O MySQL pinta outro panorama:
HEX(255)devolve'FF'(em maiusculas!) e funciona tanto com numeros quanto com strings.CONV('ff', 16, 10)passa de hex para decimal, ouUNHEX('5047')para bytes.CONV(255, 10, 16)e uma troca flexivel entre quaisquer duas bases.-- MySQL flavor SELECT HEX(255), -- 'FF' CONV('ff', 16, 10),-- '255' LPAD(HEX(15), 2, '0'); -- '0F'O ClickHouse oferece
hex(255)(tambem em maiusculas) eunhex('FF')para o inverso. Cuidado com a capitalizacao ao comparar strings entre motores. Resumo:to_hexpara numeros,encode/decodepara bytes, e o inverso viabitno PostgreSQL ouCONV/UNHEXno MySQL.