2010-09-07 73 views
1

我試圖將AD maxpwdAge(一個64位整數)轉換爲幾天。使用二進制補碼的負整數的Perl函數

According to Microsoft

採用IAD設備接口的Get方法來檢索域的maxPwdAge屬性(第5行)的值。

注意,我們在VBScript中使用Set關鍵字來初始化名爲objMaxPwdAge的變量 - 用於存儲由Get返回的值的變量。這是爲什麼?

當您獲取一個64位大整數時,ADSI不會返回一個巨大的標量值。相反,ADSI會自動返回一個IADsLargeInteger對象。您可以使用IADsLargeInteger接口的HighPartLowPart屬性來計算大整數的值。正如您可能已經猜到的那樣,HighPart獲得高階32位,並且LowPart獲得低階32位。您可以使用以下公式將HighPartLowPart轉換爲大整數的值。

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?

回答

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"; 
+0

雅..它將但如何生成高部分和低部分(例如:值是-37108517437440) – Tree 2010-09-07 13:11:03

+0

我以爲你有高和低的32位部分,並希望建立原始的64位值。你有什麼? – 2010-09-07 13:14:48

+0

我有64位單值整數值:-37108517437440 – Tree 2010-09-07 13:16:55

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上正常工作,你必須牢記所有的精度問題。