merchant

Merchant backend to process payments, run by merchants
Log | Files | Refs | Submodules | README | LICENSE

pg_base32_crockford.sql (2045B)


      1 --
      2 -- This file is part of TALER
      3 -- Copyright (C) 2026 Taler Systems SA
      4 --
      5 -- TALER is free software; you can redistribute it and/or modify it under the
      6 -- terms of the GNU General Public License as published by the Free Software
      7 -- Foundation; either version 3, or (at your option) any later version.
      8 --
      9 -- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
     10 -- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
     11 -- A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
     12 --
     13 -- You should have received a copy of the GNU General Public License along with
     14 -- TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
     15 --
     16 
     17 DROP FUNCTION IF EXISTS base32_crockford;
     18 CREATE FUNCTION base32_crockford(data BYTEA)
     19 RETURNS TEXT
     20 LANGUAGE plpgsql
     21 IMMUTABLE
     22 STRICT
     23 PARALLEL SAFE
     24 AS $$
     25 DECLARE
     26     alphabet TEXT := '0123456789ABCDEFGHJKMNPQRSTVWXYZ';
     27     chars     TEXT[]  := '{}';
     28     bit_buf   BIGINT  := 0;   -- sliding window of accumulated bits
     29     bit_count INT     := 0;   -- how many valid bits are in bit_buf
     30     b         INT;
     31     i         INT;
     32 BEGIN
     33     IF length(data) = 0 THEN
     34         RETURN '';
     35     END IF;
     36 
     37     -- Process each byte, emitting 5-bit groups as we go
     38     FOR i IN 0 .. length(data) - 1
     39     LOOP
     40         b := get_byte(data, i);
     41         bit_buf   := (bit_buf << 8) | b;
     42         bit_count := bit_count + 8;
     43 
     44         WHILE bit_count >= 5
     45         LOOP
     46             bit_count := bit_count - 5;
     47             chars := array_append(
     48                 chars,
     49                 substr(alphabet, ((bit_buf >> bit_count) & 31)::INT + 1, 1)
     50             );
     51         END LOOP;
     52     END LOOP;
     53 
     54     -- Flush any remaining bits (zero-padded to 5)
     55     IF bit_count > 0
     56     THEN
     57         chars := array_append(
     58             chars,
     59             substr(alphabet, ((bit_buf << (5 - bit_count)) & 31)::INT + 1, 1)
     60         );
     61     END IF;
     62     RETURN array_to_string(chars, '');
     63 END;
     64 $$;
     65 COMMENT ON FUNCTION base32_crockford(BYTEA)
     66   IS 'Encodes binary data using Crockford Base32';