字符串为二进制并使用纯SQLite返回

时间:2018-04-01 18:24:49

标签: sql sqlite

我知道如何将字符串转换为二进制表示。

y axis

结果是WITH string(s) AS (VALUES('string')), bytes(i, j, b, s) AS ( VALUES(1, 0, '', (SELECT s FROM string)) UNION ALL SELECT i + 1, j + 1, UNICODE(SUBSTR(s, i, 1)), s FROM bytes LIMIT (SELECT LENGTH(s) + 1 FROM string) ), octets(i, o) AS ( VALUES(1, '') UNION ALL SELECT i + 1, '' FROM octets LIMIT (SELECT COUNT(b) FROM bytes WHERE b <> '') ) SELECT replace(group_concat(( WITH bin(n, c) AS ( VALUES(7, '') UNION ALL SELECT n - 1, CASE (b >> n) & 1 WHEN 1 THEN '1' ELSE '0' END FROM bin LIMIT 9 ) SELECT replace(group_concat(c), ',', '') FROM bin )), ',', '') FROM bytes b JOIN octets o ON b.j = o.i; 。是否可以使用纯SQLite将它们转换回常规视图?这是否需要临时表,或者可以使用嵌套的"011100110111010001110010011010010110111001100111"限制来解决?

2 个答案:

答案 0 :(得分:2)

您应该创建函数或在应用程序级别执行此操作,但让我们尝试使用纯SQL:

WITH RECURSIVE cnt(x) AS (
     SELECT 1
     UNION ALL
     SELECT x+1 FROM cnt
     LIMIT 100
), bin(b) AS(
   VALUES ('011100110111010001110010011010010110111001100111')
  )
SELECT 
    GROUP_CONCAT(CHAR(
    SUBSTR(SUBSTR(b, 1+(c.x-1)*8, 8), 1, 1) * 128 +
    SUBSTR(SUBSTR(b, 1+(c.x-1)*8, 8), 2, 1) * 64 +
    SUBSTR(SUBSTR(b, 1+(c.x-1)*8, 8), 3, 1) * 32 +
    SUBSTR(SUBSTR(b, 1+(c.x-1)*8, 8), 4, 1) * 16 +
    SUBSTR(SUBSTR(b, 1+(c.x-1)*8, 8), 5, 1) * 8 +
    SUBSTR(SUBSTR(b, 1+(c.x-1)*8, 8), 6, 1) * 4 +
    SUBSTR(SUBSTR(b, 1+(c.x-1)*8, 8), 7, 1) * 2 +
    SUBSTR(SUBSTR(b, 1+(c.x-1)*8, 8), 8, 1) * 1 
    ), '') AS result
FROM bin b
JOIN cnt c
  ON c.x <= LENGTH(b)/8;

<强> DBFiddle Demo

工作原理:

  • cnt(x)tally / number table
  • bin(b)我们的二进制表示
  • 主要查询
    • 将48个字符拆分为8个块
    • 转换为数字
    • CHAR - &gt;获取字符串表示
    • group_concat - 获取一个字符串

当然,有很多改进的地方。

答案 1 :(得分:0)

我找到了更加漂亮的方式this。将字符串转换为二进制表示:

WITH bits(i, s) AS (
   VALUES(1, '') UNION ALL
   SELECT i + 1, (
      WITH bin(p, b) AS (
         VALUES(7, '') UNION ALL
         SELECT p - 1, (UNICODE(
            SUBSTR('this is test string', i, 1)
         ) >> p) & 1 FROM bin LIMIT 9
      ) SELECT group_concat(b, '') FROM bin
   ) AS c FROM bits WHERE c <> ''
) SELECT group_concat(s, '') FROM bits;

然后回来:

WITH octets(c, s) AS (
   VALUES('', '0111010001101000011010010111001100100000011010' ||
       '01011100110010000001110100011001010111001101110100001' ||
       '00000011100110111010001110010011010010110111001100111')
   UNION ALL
   SELECT SUBSTR(s, 1, 8), SUBSTR(s, 9) FROM octets WHERE s <> ''
) SELECT group_concat(CHAR(
   SUBSTR(c, 1, 1) * 128 + SUBSTR(c, 2, 1) * 64 +
   SUBSTR(c, 3, 1) * 32  + SUBSTR(c, 4, 1) * 16 +
   SUBSTR(c, 5, 1) * 8   + SUBSTR(c, 6, 1) * 4  +
   SUBSTR(c, 7, 1) * 2   + SUBSTR(c, 8, 1)
), '') FROM octets WHERE c <> '';