【问题标题】:How does SUBSTRING work with a VARBINARY field?SUBSTRING 如何与 VARBINARY 字段一起使用?
【发布时间】:2015-03-01 13:37:02
【问题描述】:

请参阅下面的 DDL:

CREATE TABLE #Person (id decimal(25,0))
INSERT INTO #Person values (153121432060080000944513)

以及下面的SQL语句:

select substring(HASHBYTES('MD5', 
CAST(id AS varchar(24))),1,4)
from #person

在阅读 Hashbytes 参考 (https://msdn.microsoft.com/en-GB/library/ms174415.aspx) 后,我了解到返回了 VARBINARY。 substring 函数如何与 VARBINARY 一起工作。上面的 SUBSTRING 函数返回以下内容:

0x05DDF8D9

这超过四个字符的长度。我知道 0x 表示 VARBINARY。为什么子串的字符多于四个?

【问题讨论】:

  • 该值被编码为十六进制,因此输出中的每个字符代表四位——通常是存储中字符的一半。 0x 表示字符串中的每个字符的两个字符。所以,这是四个字符。

标签: sql tsql


【解决方案1】:

您将十六进制输出与字符串混淆了。您的字符串很可能由使用 ASCII 编码的单字节字符组成。每个字节 - 由 8 位组成 - 代表一个字符,通常通过将 0 到 127 之间的值映射到我们知道和喜爱的东西。 “32”是一个空格。 “65”是“A”(大写)。

问题是:当“字符串”真的是“二进制”时,如何表示?突然间,计算机不再有一个很好的字符集来映射每个字符。而且,有些字符会造成问题——“删除”、“换行”、“回车”和零值都是 ASCII 字符,无法识别打印输出。

让我们下一层。字母 A 由位序列“01000001”表示(这是数字 65 的二进制形式)。一种常用的表示方法是将其分成“0100”和“0001”两半,然后将每一半解释为一个数字。使用十六进制(以 16 为基数)数字系统,因为 4 位有 16 种可能性。前十个值很容易。它们是数字。其他六个(10 到 15)使用字母 A - F 表示。这些通常大写。按照惯例,整个值都有一个前导的“0x”前缀。

因此,“01000001”位将表示为 0x41。考虑“11001010”的另一个例子。这将成为 0xCA。如果您愿意,您还可以玩解密 0xC0DE 或“0xBEADED”或“0xFEEFIEF0E”等游戏。

对不起,这太长了。解释这一点似乎比我应该做的工作更有趣。

【讨论】:

  • 感谢您的全面回答。但是,8 位 (ascii) 是 16 (hex) 的一半,而不是双倍。对不起,我有点困惑。
  • @w0051977 。 . . 4 位可以表示从 0 到 15 的值。这就是十六进制的用途。 4 位中的“16”值恰好是 ASCII 字符中位数的两倍,这有点巧合。
猜你喜欢
  • 2016-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-23
  • 2021-12-17
相关资源
最近更新 更多