Answers:
用户名的一般规则是其长度必须少于32个字符。有效的用户名取决于您的分配。
在Debian中shadow-utils 4.1
,有一个is_valid_name
功能chkname.c
:
static bool is_valid_name (const char *name)
{
/*
* User/group names must match [a-z_][a-z0-9_-]*[$]
*/
if (('\0' == *name) ||
!((('a' <= *name) && ('z' >= *name)) || ('_' == *name))) {
return false;
}
while ('\0' != *++name) {
if (!(( ('a' <= *name) && ('z' >= *name) ) ||
( ('0' <= *name) && ('9' >= *name) ) ||
('_' == *name) ||
('-' == *name) ||
( ('$' == *name) && ('\0' == *(name + 1)) )
)) {
return false;
}
}
return true;
}
并在之前检查了用户名的长度:
bool is_valid_user_name (const char *name)
{
/*
* User names are limited by whatever utmp can
* handle.
*/
if (strlen (name) > USER_NAME_MAX_LENGTH) {
return false;
}
return is_valid_name (name);
}
通常建议仅使用以小写字母或下划线开头,后跟小写字母,数字,下划线或破折号的用户名。它们可以以美元符号结尾。用正则表达式表示:[a-z _] [a-z0-9 _-] * [$]?
在Debian上,唯一的限制是用户名既不能以短划线('-')开头,也不能包含冒号(':')或空格(空格:'',行尾:'\ n',制表符:' \ t'等)。请注意,使用斜杠('/')可能会破坏用于定义用户主目录的默认算法。
用户名最多只能包含32个字符。
因此,有一个一般性建议。实际限制取决于实现/分发的细节。在基于Debian的系统上,显然没有非常严格的约束。实际上,我只是useradd '€'
在Ubuntu盒子上试过了,就可以了。当然,这可能会破坏一些不希望使用这种不寻常用户名的应用程序。为避免此类问题,最好遵循一般建议。
很抱歉,这个问题已有将近4年的历史了,但它在Internet搜索结果中的排名很高,值得引起更多关注。
更准确的正则表达式是(是的,尽管有手册页,但我知道):
^[a-z_]([a-z0-9_-]{0,31}|[a-z0-9_-]{0,30}\$)$
希望这对某些搜索有所帮助。
分解:
^
)只用小写字母或下划线([a-z_]
)。这恰好占据1个字符。( ... )
):
{0,31}
的)字母,数字,下划线,和/或连字符([a-z0-9_-]
),OR(|
)\$
)结尾,然后$
)的字符不再。对于那些不熟悉正则表达式模式的人,您可能会问为什么美元符号在2.2中反斜杠。但不是在3中。这是因为在大多数(全部?)正则表达式变体中,美元符号表示字符串(或行等)的结尾。根据所使用的引擎,如果它是实际字符串的一部分,则需要对其进行转义(我不认为我的正则表达式引擎的顶部不会使用反斜杠作为纯表达式的转义) 。
请注意,Debian和Ubuntu取消了对完全符合POSIX / shadow上游要求的用户名的一些限制(例如,我不知道此问题是否已解决,但他们允许用户名以数字开头-实际上是导致此问题的原因错误)。如果您想保证跨平台,我建议您使用上面的正则表达式模式,而不是通过/未通过Debian,Ubuntu等检查的方法。
[abcdefghijklmnopqrstuvwxyz]
改为[a-z]
。[a-z]
在许多正则表达式引擎中,它们还匹配,例如é
,œ
甚至有时匹配多字符排序元素(例如dsz
在匈牙利语言环境中)。
java.util.regex.Pattern.matches("^[a-z_]([a-z0-9_-]{0,31}|[a-z0-9_-]{0,30}\\$)$", user);