sqlpostgresqlto_hexbitwise

to_hex no PostgreSQL: converter um inteiro em string hexadecimal

Como to_hex(int) transforma um numero em string hex para cores, mascaras de bits e depuracao de flags, como inverter e como MySQL e ClickHouse diferem.

2 min de leituraReferencesql · postgresql · to_hex · bitwise · mysql · clickhouse

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);        -- 'ff'
SELECT to_hex(4096);       -- '1000'
SELECT to_hex(16777215);   -- 'ffffff'

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:

-- 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 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:

-- 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_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.

-- 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;  -- 4096

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:

-- Round trip: int -> hex -> int
SELECT ('x' || lpad(to_hex(48879), 8, '0'))::bit(32)::int;  -- 48879

bytea e equivalentes no MySQL

Para dados binarios (bytea) em vez de um unico numero, use encode e decode com o formato hex:

-- Bytes to hex text and back
SELECT encode('PG'::bytea, 'hex');      -- '5047'
SELECT decode('5047', 'hex');           -- bytea \x5047

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.
-- 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) 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.

Pratique com exercícios reais

Resolva exercícios no treinador de SQL com correção instantânea e dicas.

Abrir o treinador