PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Convertir l'hexadécimal dans la représentation textuelle en nombre décimal

Méthodes sans SQL dynamique

Il n'y a pas de cast à partir de nombres hexadécimaux dans text représentation à un type numérique, mais nous pouvons utiliser bit(n) comme point de cheminement. Il y a des sans papiers convertit à partir de chaînes de bits (bit(n) ) aux types entiers (int2 , int4 , int8 ) - la représentation interne est compatible binaire. Citant Tom Lane :

Cela repose sur un comportement non documenté du convertisseur d'entrée de type bit, mais je ne vois aucune raison de s'attendre à ce que cela se casse. Un problème peut-être plus important est qu'il nécessite PG>=8.3 car il n'y avait pas de textto bit cast avant cela.

integer pour max. 8 chiffres hexadécimaux

Jusqu'à 8 chiffres hexadécimaux peuvent être convertis en bit(32) puis converti en integer (entier standard de 4 octets) :

SELECT ('x' || lpad(hex, 8, '0'))::bit(32)::int AS int_val
FROM  (
   VALUES
      ('1'::text)
    , ('f')
    , ('100')
    , ('7fffffff')
    , ('80000000')     -- overflow into negative number
    , ('deadbeef')
    , ('ffffffff')
    , ('ffffffff123')  -- too long
   ) AS t(hex);
   int_val
------------
          1
         15
        256
 2147483647
-2147483648
 -559038737
         -1

Postgres utilise un type entier signé, donc les nombres hexadécimaux au-dessus de '7fffffff' débordement en entier négatif Nombres. Il s'agit toujours d'une représentation unique et valide, mais la signification est différent. Si cela compte, passez à bigint; voir ci-dessous.

Pour plus de 8 chiffres hexadécimaux, les caractères les moins significatifs (en excès à droite) sont tronqués .

4 bits dans une chaîne binaire encoder 1 chiffre hexadécimal . Les nombres hexadécimaux de longueur connue peuvent être convertis en bit(n) respectif directement. Vous pouvez également remplir les numéros hexadécimaux de longueur inconnue avec des zéros non significatifs (0 ) comme démontré et converti en bit(32) . Exemple avec 7 chiffres hexadécimaux et int ou 8 chiffres et bigint :

SELECT ('x'|| 'deafbee')::bit(28)::int
     , ('x'|| 'deadbeef')::bit(32)::bigint;
  int4     | int8
-----------+------------
 233503726 | 3735928559

bigint pour max. 16 chiffres hexadécimaux

Jusqu'à 16 chiffres hexadécimaux peuvent être convertis en bit(64) puis contraint à bigint (int8 , entier de 8 octets) - débordant à nouveau en nombres négatifs dans la moitié supérieure :

SELECT ('x' || lpad(hex, 16, '0'))::bit(64)::bigint AS int8_val
FROM  (
   VALUES
      ('ff'::text)
    , ('7fffffff')
    , ('80000000')
    , ('deadbeef')
    , ('7fffffffffffffff')
    , ('8000000000000000')     -- overflow into negative number
    , ('ffffffffffffffff')
    , ('ffffffffffffffff123')  -- too long
   ) t(hex);
       int8_val
---------------------
                 255
          2147483647
          2147483648
          3735928559
 9223372036854775807
-9223372036854775808
                  -1
                  -1

uuid pour max. 32 chiffres hexadécimaux

L'uuid de Postgres le type de données n'est pas un type numérique . Mais c'est le type le plus efficace dans Postgres standard pour stocker jusqu'à 32 chiffres hexadécimaux, n'occupant que 16 octets de stockage. Il y a une distribution directe à partir de text en uuid (pas besoin de bit(n) comme waypoint), mais exactement 32 chiffres hexadécimaux sont requis.

SELECT lpad(hex, 32, '0')::uuid AS uuid_val
FROM  (
   VALUES ('ff'::text)
        , ('deadbeef')
        , ('ffffffffffffffff')
        , ('ffffffffffffffffffffffffffffffff')
        , ('ffffffffffffffffffffffffffffffff123') -- too long
   ) t(hex);
              uuid_val
--------------------------------------
 00000000-0000-0000-0000-0000000000ff
 00000000-0000-0000-0000-0000deadbeef
 00000000-0000-0000-ffff-ffffffffffff
 ffffffff-ffff-ffff-ffff-ffffffffffff
 ffffffff-ffff-ffff-ffff-ffffffffffff

Comme vous pouvez le voir, la sortie standard est une chaîne de chiffres hexadécimaux avec des séparateurs typiques pour UUID.

hachage md5

Ceci est particulièrement utile pour stocker les hachages md5 :

SELECT md5('Store hash for long string, maybe for index?')::uuid AS md5_hash;
           md5_hash
--------------------------------------
 02e10e94-e895-616e-8e23-bb7f8025da42

Voir :

  • Quel est le type de données optimal pour un champ MD5 ?