SQL: Сравните, если строка является MD5-хешем? - PullRequest
1 голос
/ 21 февраля 2012

Вопрос:

Мне нужно СРАВНИТЬ, если строка является хешем MD5 в SQL.

Я нашел эту PHP-функцию:

function isValidMd5($md5)
{
    return !empty($md5) && preg_match('/^[a-f0-9]{32}$/', $md5);
}

Поскольку в SQL отсутствует синтаксис {32}, я просто дублирую [a-f0-9] 32 раза:

IF '200ceb26807d6bf99fd6f4f0d1ca54d4' LIKE '[a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9]' 
BEGIN
    PRINT 'YES'
END
ELSE
BEGIN
    PRINT 'NO'
END 

Однако, чтобы избежать возможного столкновения с именем пользователя, состоящим из 32 [a-f], что маловероятно, я хочу сделать подобное сравнение в верхнем регистре.

Но если для целей тестирования я делаю:

IF 'E' COLLATE Latin1_General_CS_AS  LIKE ('[a-f0-9]' COLLATE Latin1_General_CS_AS )
BEGIN
    PRINT 'yes'
END
ELSE
BEGIN
    PRINT 'no'
END 

Я понимаю, да, а не нет.
Однако COLLATE Latin1_General_CS_AS должен сделать его чувствительным к регистру ...

Как можно сделать LIKE в этом случае чувствительным к регистру?

Ответы [ 3 ]

2 голосов
/ 21 февраля 2012

Лучше перевернуть чек и упростить его обслуживание, проверив наличие какой-либо одной вещи, которая сделает его неудачнымЭто означает, что вам не нужно повторять [0-9a-f] 32 раза в коде.

IF LEN(@myValue) <> 32 OR LOWER(@myValue) LIKE '%[^0-9a-f]%' 
BEGIN
   -- No it isn't
END ELSE BEGIN
   -- Yes it is
END

то есть, если это не 32 символа ИЛИ он содержит символ вне шестнадцатеричного набора, то произойдет сбой.

2 голосов
/ 21 февраля 2012

Будет ли это работать?

IF myValue LIKE '[a-f0-9][...]' 
and LOWER(myValue) = myValue
1 голос
/ 26 апреля 2012

ОК, после кропотливого изучения проблемы, это лучшее решение:

Обратите внимание, что важно писать ABCDEF вместо A-F, потому что в противном случае любая буква между A и F не чувствительна к регистру.

(как для A-F: обратите внимание, что маленький 'a' является граничным случаем, поскольку он не находится в этом диапазоне, в отличие от маленького 'b'.)

DECLARE @myValue varchar(100)

--SET @myValue = '66B9E31D4C59D3802279515F9B1A6222'
SET @myValue   = '66B9E31D4C59D3802279515F9B1B6222'


IF LEN(@myValue) <> 32 OR @myValue LIKE '%[^0-9ABCDEF]%' COLLATE Latin1_General_CS_AS   
BEGIN 
   print 'No it isn''t'
END ELSE BEGIN 
   print 'Yes it is '
END 

И как функция проверки MD5:

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[fn_IsMd5Hash]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
DROP FUNCTION [dbo].[fn_IsMd5Hash]
GO




-- ========================================================================
-- Author:  
-- Create date:   26.04.2012
-- Last modified: 26.04.2012
-- Description:   Überprüfen ob string ein MD5-Hash ist
-- ========================================================================

-- PRE:  varchar(50) 
-- POST: True/False 
-- PRINT dbo.[fn_IsMd5Hash]('66B9E31D4C59D3802279515F9B1B6222') 
CREATE  FUNCTION [dbo].fn_IsMd5Hash(@strInputAnything varchar(50)) 
    RETURNS bit 
AS
BEGIN 
    DECLARE @bIsMd5Hash AS bit 

    SET @bIsMd5Hash = 'false' 

    IF LEN(@strInputAnything) = 32 AND NOT @strInputAnything LIKE '%[^0-9ABCDEF]%' COLLATE Latin1_General_CS_AS 
        SET @bIsMd5Hash = 'true' 

    RETURN @bIsMd5Hash 
END


GO
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...