2010-09-07 5 views
1

J'essaie de convertir AD maxpwdAge (un entier de 64 bits) en un nombre de jours.Fonction Perl pour les entiers négatifs utilisant le complément 2

According to Microsoft:

utilise la méthode de l'interface IADs Get pour récupérer la valeur de l'attribut maxPwdAge (ligne 5) du domaine.

Notez que nous utilisons le mot-clé Set dans VBScript pour initialiser la variable nommée objMaxPwdAge -la variable utilisée pour stocker la valeur renvoyée par Get. Pourquoi donc?

Lorsque vous récupérez un entier de 64 bits, ADSI ne renvoie pas une valeur scalaire géante. Au lieu de cela, ADSI renvoie automatiquement un objet IADsLargeInteger. Vous utilisez les propriétés IADsLargeInteger de l'interface HighPart et LowPart pour calculer la valeur du grand entier. Comme vous l'avez peut-être deviné, HighPart obtient les 32 bits de poids fort, et LowPart obtient les 32 bits de poids faible. Vous utilisez la formule suivante pour convertir HighPart et LowPart à la valeur du grand entier.

Le code existant dans VBScript de la même page:

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 

Comment puis-je faire en Perl?

Répondre

1

Endianness peut entrer en cela, mais vous pouvez être en mesure de dire

#!/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

ya .. mais comment générer la partie haute et basse (par exemple: la valeur est -37108517437440) – Tree

+0

Je pensais que vous aviez les parties 32 bits hautes et basses et que vous vouliez construire la valeur originale de 64 bits . Qu'est-ce que tu as? –

+0

J'ai 64 bits nombre entier chanté valeur: -37108517437440 – Tree

0

Est-ce que je manque quelque chose? Autant que je puisse dire de votre question, votre problème n'a rien à voir avec le complément à 2. Pour autant que je peux dire, tout ce que vous devez/voulez faire est

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; 

Notez que j'utilise délibérément 2 constantes séparées, et je divise par eux dans l'ordre, parce que maintient les diviseurs plus petite que la portée d'un Entier 32 bits. Si vous voulez écrire différemment et que vous voulez que cela fonctionne correctement sur les perls 32 bits, vous devez garder à l'esprit tous les problèmes de précision.

Questions connexes