我有一个表,其中列出了所有可能的组合(特殊字符,数字等)的密码。我想提取具有超过5个特殊字符的所有密码的列表。
此查询需要帮助
PandasProfiling
答案 0 :(得分:1)
警告::您的问题表明您将密码作为纯文本存储在数据库中。
这是主要安全风险 。密码应存储为salted hash,而不是加密的,并且永远不要存储为纯文本(感谢塞巴斯蒂安·布罗施(Sebastian Brosch)的注意)。
话虽如此,这是您的问题的答案:
一种方法是将字符串分成单个字符,然后仅用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]%'
当然,如果您已经有了理货记录表,则无需即时创建理货记录cte:
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]%'
以及使用带有“密码”列的“登录”表的完整版本: (以及填充即时提示CTE的另一种方法)
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#$^#%
答案 1 :(得分:0)
由于您的问题是如何计算列中的特殊字符?,并且您没有提供正在使用的版本,因此可以使用 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 |
+-----+
这里是 db<>fiddle
这也是另一种方式
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 <> '';
更新:
我想提取包含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;
答案 2 :(得分:0)
根据您的问题,我了解到您在此将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;
答案 3 :(得分:0)