Количество специальных символов в столбце - PullRequest
0 голосов
/ 02 мая 2019

У меня есть таблица со списком паролей во всех возможных комбинациях (специальные символы, цифры и т. Д.). Я хочу извлечь список всех паролей, которые имеют более 5 специальных символов.

Нужна помощь по этому запросу

Select Password from Login where Password like `%[a-zA-Z0-9]%` and Len(`%[a-zA-Z0-9]%`) >=5

Ответы [ 4 ]

1 голос
/ 02 мая 2019

Предупреждение: Ваши вопросы говорят о том, что вы храните пароли как обычный текст в вашей базе данных.
Это серьезная угроза безопасности . Пароли должны храниться как соленый хеш , без шифрования и никогда не в виде простого текста (Спасибо Себастьяну Броше за то, что обратил на это внимание).

Сказав это, вот ответ на ваш вопрос:

Один из способов сделать это - разбить строку на отдельные символы, а затем просто запросить с помощью count:

DECLARE @str nvarchar(30) = 'shS46@($8jr4';
With N10 AS
(
    SELECT N
    FROM (VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9))V(N)
), Tally AS
(
    SELECT TOP(LEN(@str)) ROW_NUMBER() OVER(ORDER BY @@SPID) As N
    FROM N10 ten
    CROSS JOIN N10 hundred 
    -- Passwords are usually 10-20 chars max length. 
    -- If you need more you can add another cross join to get 1000.
), Chars AS
(
    SELECT SUBSTRING(@str, N, 1) As C
    FROM Tally
)

SELECT COUNT(*)
FROM Chars
WHERE C NOT LIKE '%[A-Za-z0-9]%'

Конечно, если у вас уже есть таблица подсчета, вам не нужно создавать счет на лету:

With Chars AS
(
    SELECT SUBSTRING(@str, N, 1) As C
    FROM Tally
    WHERE N <= LEN(@str)
)

SELECT COUNT(*)
FROM Chars
WHERE C NOT LIKE '%[A-Za-z0-9]%'

И полная версия, которая использует таблицу входа в систему со столбцом пароля: (и еще один способ заполнить подсчет на лету)

CREATE TABLE Login
(
    Password nvarchar(20)
);

INSERT INTO Login (Password) VALUES
('n9$%^Usj4jjr'),
('Nehj47$%^$'),
('MNAtokay543^A36#$^#%'),
('(*&^#$^dfh$%&'),
('$%^h345nfs54y');



With Tally AS 
(
    SELECT TOP 20 ROW_NUMBER() OVER(ORDER BY @@SPID) As N
    FROM sys.objects

), Chars AS
(
    SELECT Password, SUBSTRING(Password, N, 1) As C
    FROM Login
    CROSS JOIN Tally 
    WHERE N <= LEN(Password)
)

SELECT Password
FROM Chars
GROUP BY Password
HAVING COUNT(CASE WHEN C NOT LIKE '%[A-Za-z0-9]%' THEN 1 END) > 5

Результаты:

Password
(*&^#$^dfh$%&
MNAtokay543^A36#$^#%
0 голосов
/ 02 мая 2019

Используя NGrams8K , вы можете просто сделать это:

--Sample data
CREATE TABLE #Login(ID INT IDENTITY, PW nvarchar(20));
INSERT INTO #Login (PW) VALUES
('n9$%^Usj4jjr'),
('Nehj47$%^$'),
('MNAtokay543^A36#$^#%'),
('(*&^#$^dfh$%&'),
('$%^h345nfs54y');

SELECT      l.ID, SpecialChars = COUNT(*)
FROM        #Login AS l
CROSS APPLY dbo.NGrams8k(l.PW,1) AS ng
WHERE       PATINDEX('[^a-zA-Z0-9]',ng.token) = 1
GROUP BY    l.ID
HAVING      COUNT(*) > 5;

Возвращает:

ID          SpecialChars
----------- ------------
3           6
4           10
0 голосов
/ 02 мая 2019

Исходя из вашего вопроса, я понимаю, что вы называете nonalphanumberic символами в качестве специальных символов здесь. Если это так, вы можете получить его двумя способами.

1) Если вам известен весь список специальных символов, которые могут появиться в вашем столбце, и если у вас нет прав на создание function.

SELECT * from test 
WHERE (len(COL)- len(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
       REPLACE(REPLACE(REPLACE(REPLACE(col,
        '!',''),'@',''),'#',''),'$',''),'%',''),
        '^',''),'&',''),'*',''),' ','')) ) >=5;

2) Если вы можете создать function.

Create Function [dbo].[RemoveNonAlphaCharacters](@Temp VarChar(1000))
Returns VarChar(1000)
AS
Begin

    Declare @KeepValues as varchar(50)
    Set @KeepValues = '%[^a-Z0-9]%'
    While PatIndex(@KeepValues, @Temp) > 0
        Set @Temp = Stuff(@Temp, PatIndex(@KeepValues, @Temp), 1, '')

    Return @Temp
End

А потом select. Благодаря G Mastros за вышеуказанную функцию

Select * from test where (len(col) - len(dbo.RemoveNonAlphaCharacters(col))) > =5;

DB FIDDLE

0 голосов
/ 02 мая 2019

Поскольку ваш вопрос Как рассчитать специальные символы в столбце? и вы не указали версию, над которой работаете, вы можете использовать TRANSLATE() , REPLICATE() и REPLACE() функционирует как

CREATE TABLE [Login](
  [Password] VARCHAR(45)
);

INSERT INTO [Login] VALUES
('Password'),
('abc@def'),
('a@b@c_d_e/f'),
('Normal');

DECLARE @SC VARCHAR(3) = '@_/';

WITH CTE AS
(
  SELECT *, REPLACE(TRANSLATE([Password], @SC, REPLICATE(' ', LEN(@SC))), ' ', '') Result
  FROM [Login] 
)
SELECT SUM(LEN([Password]) - LEN(Result)) Cnt
FROM CTE;

Возвращает:

+-----+
| Cnt |
+-----+
|   6 |
+-----+

Вот дБ <> скрипка

А также вот еще один способ сделать это

CREATE TABLE [Login](
  [Password] VARCHAR(45)
);

INSERT INTO [Login] VALUES
('Password'),
('abc@def'),
('a@b@c_d_e/f'),
('Normal Words');

WITH Chars AS
(
  SELECT SUBSTRING([Password], Number + 1, 1) Chr
  FROM [Login] CROSS JOIN master..spt_values
  WHERE [Type] = 'P'
)
SELECT COUNT(1) Cnt
FROM Chars
WHERE Chr NOT LIKE '%[A-Za-z0-9]%' AND Chr <> '';

Демо

UPDATE:

Я хочу извлечь список всех паролей, которые содержат более 5 специальных символов.

CREATE TABLE [Login](
  [Password] VARCHAR(45)
);

INSERT INTO [Login] VALUES
('Password'),
('abc@def'),
('a@b@c_d_e/f$'),
('Normal Words'),
('My_$P@$$word_/');

DECLARE @SC VARCHAR(3) = '$@_/'; --It's just an example
SELECT *
FROM [Login]
WHERE LEN([Password]) - LEN(REPLACE(
                                   TRANSLATE([Password], 
                                             @SC, 
                                             REPLICATE(CHAR(9), LEN(@SC))
                                            ),
                                   CHAR(9), '')) >= 5;

Демо

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