事情的起因是我需要从域里面读出所有被禁用的域账号作清理。
然后发现域账号的属性里有一项userAccountControl表示账号的启用状态的。
1 该项的状态值允许有多个,并且只存储它们的和。
2 所有状态值为2的n次方。(1,2,4,8...)
附微软官方资料
属性标志 十六进制值 十进制值
SCRIPT 0x0001 1
ACCOUNTDISABLE 0x0002 2
HOMEDIR_REQUIRED 0x0008 8
LOCKOUT 0x0010 16
PASSWD_NOTREQD 0x0020 32
PASSWD_CANT_CHANGE 0x0040 64
ENCRYPTED_TEXT_PWD_ALLOWED 0x0080 128
TEMP_DUPLICATE_ACCOUNT 0x0100 256
NORMAL_ACCOUNT 0x0200 512
利用ladp协议读取出来的总和值,如何反推出来由哪几个状态组合而成的?
事实我上的目的无非就是想确认账号里有没有被禁用状态(值为2)。
注:一个用户被禁用后,肯定有2的状态,但还会有若干个其它状态。最后归纳为数学问题,已知数列为2的那次方(1,2,4,8,16...)
从中抽取任意个(各不相同)相加,已知和为N,如何反推出来这几个加数是多少?
然后发现域账号的属性里有一项userAccountControl表示账号的启用状态的。
1 该项的状态值允许有多个,并且只存储它们的和。
2 所有状态值为2的n次方。(1,2,4,8...)
附微软官方资料
属性标志 十六进制值 十进制值
SCRIPT 0x0001 1
ACCOUNTDISABLE 0x0002 2
HOMEDIR_REQUIRED 0x0008 8
LOCKOUT 0x0010 16
PASSWD_NOTREQD 0x0020 32
PASSWD_CANT_CHANGE 0x0040 64
ENCRYPTED_TEXT_PWD_ALLOWED 0x0080 128
TEMP_DUPLICATE_ACCOUNT 0x0100 256
NORMAL_ACCOUNT 0x0200 512
利用ladp协议读取出来的总和值,如何反推出来由哪几个状态组合而成的?
事实我上的目的无非就是想确认账号里有没有被禁用状态(值为2)。
注:一个用户被禁用后,肯定有2的状态,但还会有若干个其它状态。最后归纳为数学问题,已知数列为2的那次方(1,2,4,8,16...)
从中抽取任意个(各不相同)相加,已知和为N,如何反推出来这几个加数是多少?
{
List<int> list = new List<int>();
for (int i = 1; ; i *= 2)
{
bool flag = (sum & i) != 0;
if (flag)
{
list.Add(i);
}
else
break;
}
return list;
}调用
//调用
List<int> temp=GetList(63);
/*
* 1 2 4
*/
private List<int> GetList(int sum)
{
List<int> list = new List<int>();
for (int i = 1; i<sum; i *= 2)
{
bool flag = (sum & i) != 0;
if (flag)
{
list.Add(i);
}
}
return list;
}
N值有两种结果:奇数或偶数。凡是与1相加的必定为奇数,其他的相加则必定是偶数
if(N is 奇数)
{
N = N-1;..............//此时这个N必定是2的n次方的组合相加
}
else if(N is 偶数)
{
.....//这个N也将是2的n次方相加
}
...至于大括号里要如何取处理还没想到
ACCOUNTDISABLE 0x0002 2
HOMEDIR_REQUIRED 0x0008 8
LOCKOUT 0x0010 16
PASSWD_NOTREQD 0x0020 32
PASSWD_CANT_CHANGE 0x0040 64
ENCRYPTED_TEXT_PWD_ALLOWED 0x0080 128
TEMP_DUPLICATE_ACCOUNT 0x0100 256
NORMAL_ACCOUNT 0x0200 512
把这些值转为二进制,你就清楚了1 = 1;
2 = 10
4 = 100;
8 = 1000;
16=10000;
32=100000;
64
只要和相应位 与运算,就可以得出结果
例如 求 ACCOUNTDISABLE
if(accountdisable&0x2!=0)
禁用
else
启用
可以证明sum肯定小于2^(nx +1 ),且大于或等于2^nx。
所以,nx的值为(long)Math.Log(2,sum);
将sum - 2^x 得到 sum1, 循环用上述方法,直到刚好有一个2^ni等于sumk或者sumk=1。代码才刚学,思路先奉上,希望楼主喜欢
这是我的代码
我测了一下,试了几个值,结果都是正确的。
=======================
static void Main(string[] args)
{
int sum;
string strSum = Console.ReadLine();
sum = Convert.ToInt32(strSum);
List<int> ln = new List<int>();
int n;
while(sum>0)
{
n = (int)Math.Log(sum, 2);
sum -= (int)Math.Pow(2, n);
ln.Add(n);
}
if (ln.Count>0)
{
for (int i = 0; i < ln.Count;i++ )
{
Console.WriteLine(ln[i]);
}
}
Console.ReadKey();
}
每位代表一个开关。
你只需要做右移位->判断类型->加入属性列表。就行了。