我正在尝试将AD maxpwdAge
(64位整数)转换为若干天。
使用IADs接口的
Get
方法检索域maxPwdAge
属性的值(第5行)。请注意,我们在VBScript中使用
Set
关键字来初始化名为objMaxPwdAge
的变量 - 用于存储Get
返回的值的变量。那是为什么?当您获取64位大整数时,ADSI不会返回一个巨大的标量值。相反,ADSI会自动返回
IADsLargeInteger
个对象。您可以使用IADsLargeInteger
接口的HighPart
和LowPart
属性来计算大整数的值。您可能已经猜到,HighPart
获得高位32位,LowPart
获得低位32位。您可以使用以下公式将HighPart
和LowPart
转换为大整数的值。
来自同一页面的VBScript中的现有代码:
Const ONE_HUNDRED_NANOSECOND = .000000100 ' .000000100 is equal to 10^-7 Const SECONDS_IN_DAY = 86400 Set objDomain = GetObject("LDAP://DC=fabrikam,DC=com") ' LINE 4 Set objMaxPwdAge = objDomain.Get("maxPwdAge") ' LINE 5 If objMaxPwdAge.LowPart = 0 Then WScript.Echo "The Maximum Password Age is set to 0 in the " & _ "domain. Therefore, the password does not expire." WScript.Quit Else dblMaxPwdNano = Abs(objMaxPwdAge.HighPart * 2^32 + objMaxPwdAge.LowPart) dblMaxPwdSecs = dblMaxPwdNano * ONE_HUNDRED_NANOSECOND ' LINE 13 dblMaxPwdDays = Int(dblMaxPwdSecs / SECONDS_IN_DAY) ' LINE 14 WScript.Echo "Maximum password age: " & dblMaxPwdDays & " days" End If
我如何在Perl中执行此操作?
答案 0 :(得分:1)
Endianness可能会出现这种情况,但您可能会说
#!/usr/bin/perl
use strict;
use warnings;
my $num = -37_108_517_437_440;
my $binary = sprintf "%064b", $num;
my ($high, $low) = $binary =~ /(.{32})(.{32})/;
$high = oct "0b$high";
$low = oct "0b$low";
my $together = unpack "q", pack "LL", $low, $high;
print "num $num, low $low, high $high, together $together\n";
答案 1 :(得分:0)
我错过了什么吗?据我所知,你的问题与2的补码没什么关系。据我所知,你需要/想做的就是
use Math::BigInt;
use constant MAXPWDAGE_UNIT_PER_SEC => (
1000 # milliseconds
* 1000 # microseconds
* 10 # 100 nanoseconds
);
use constant SECS_PER_DAY => (
24 # hours
* 60 # minutes
* 60 # seconds
);
my $maxpwdage_full = ( Math::BigInt->new( $maxpwdage_highpart ) << 32 ) + $maxpwdage_lowpart;
my $days = $maxpwdage_full / MAXPWDAGE_UNIT_PER_SEC / SECS_PER_DAY;
请注意,我故意使用2个独立的常量,并按顺序除以它们,因为这会使除数小于32位整数的范围。如果你想用另一种方式编写它并希望它在32位perls上正常工作,你必须记住所有的精度问题。