Zinthose Posted September 11, 2008 Share Posted September 11, 2008 (edited) Greetings, I'm trying to determine all the possible permutations of a collection of bit flags so I have all the possible values that Altiris. Currently I'm using a method to iterate through all int32 values performing a BitAnd looking for matches. This is very inefficient and also takes a long time. Anyone have any tips to speed up the process? ;## Determine all permutations of Bit Flags #Include <Array.au3> Global $BaseFlag = 512 Global $SuccessFlags = 0x4 + 0x10 + 0x2000 + 0x20000 + 0x40000 ConsoleWrite("! " & _Permutations($BaseFlag, $SuccessFlags) & @CRLF) Func _Permutations ($BaseFlag, $SuccessFlags) Local $SuccessCodes = "" Local $TestNumber = 1 Local $TestBit = 0 Local $Pattern = "" ConsoleWrite("! Please Wait... This can take a very long time to calculate all possible permutations." & @CRLF) While True $TestBit = BitAND($SuccessFlags, $TestNumber) + $BaseFlag $TestBit = BitOR($TestBit, $BaseFlag) If $TestBit <> 0 Then $Pattern = "(\A|,)" & String($TestBit) & "(\z|,)" If StringRegExp($SuccessCodes, $Pattern) = 0 Then If $SuccessCodes <> "" Then $SuccessCodes &= "," $SuccessCodes &= String($TestBit) EndIf EndIf ;$TestBit = BitShift($TestBit, -1) If $TestNumber = 0x7FFFFFFF Or $TestNumber >= $SuccessFlags Then ExitLoop; <== Added "Or $TestNumber >= $SuccessFlags" which will shorten the process time as long as no high value bit flag is in use or even the negative bit. $TestNumber += 1 WEnd Return $SuccessCodes EndFunc Edited September 11, 2008 by Zinthose --- TTFN Link to comment Share on other sites More sharing options...
PsaltyDS Posted September 11, 2008 Share Posted September 11, 2008 Greetings, I'm trying to determine all the possible permutations of a collection of bit flags so I have all the possible values that Altiris. Currently I'm using a method to iterate through all int32 values performing a BitAnd looking for matches. This is very inefficient and also takes a long time. Anyone have any tips to speed up the process? ;## Determine all permutations of Bit Flags #Include <Array.au3> Global $BaseFlag = 512 Global $SuccessFlags = 0x4 + 0x10 + 0x2000 + 0x20000 + 0x40000 ConsoleWrite("! " & _Permutations($BaseFlag, $SuccessFlags) & @CRLF) Func _Permutations ($BaseFlag, $SuccessFlags) Local $SuccessCodes = "" Local $TestNumber = 1 Local $TestBit = 0 Local $Pattern = "" ConsoleWrite("! Please Wait... This can take a very long time to calculate all possible permutations." & @CRLF) While True $TestBit = BitAND($SuccessFlags, $TestNumber) + $BaseFlag $TestBit = BitOR($TestBit, $BaseFlag) If $TestBit <> 0 Then $Pattern = "(\A|,)" & String($TestBit) & "(\z|,)" If StringRegExp($SuccessCodes, $Pattern) = 0 Then If $SuccessCodes <> "" Then $SuccessCodes &= "," $SuccessCodes &= String($TestBit) EndIf EndIf ;$TestBit = BitShift($TestBit, -1) If $TestNumber = 0x7FFFFFFF Or $TestNumber >= $SuccessFlags Then ExitLoop; <== Added "Or $TestNumber >= $SuccessFlags" which will shorten the process time as long as no high value bit flag is in use or even the negative bit. $TestNumber += 1 WEnd Return $SuccessCodes EndFunc You only need a bit per value to permutate (5 bits = 32 permutations = .003sec on my computer): Global $BaseFlag = 512 Global $SuccessFlags[5] = [0x4, 0x10, 0x2000, 0x20000, 0x40000] $Results = "" $iTimer = TimerInit() For $n = 0 To (2^5) - 1 $Test = $BaseFlag For $b = 0 To 4 If BitAND(2^$b, $n) Then $Test += $SuccessFlags[$b] Next $Results &= "0x" & Hex($Test,5) & @CRLF Next $Results = StringTrimRight($Results, 1) $nTimer = Round(TimerDiff($iTimer)/1000, 3) ConsoleWrite("$Results in " & $nTimer & "sec" & @LF & $Results & @LF) Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
Zinthose Posted September 11, 2008 Author Share Posted September 11, 2008 You only need a bit per value to permutate (5 bits = 32 permutations = .003sec on my computer): Global $BaseFlag = 512 Global $SuccessFlags[5] = [0x4, 0x10, 0x2000, 0x20000, 0x40000] $Results = "" $iTimer = TimerInit() For $n = 0 To (2^5) - 1 $Test = $BaseFlag For $b = 0 To 4 If BitAND(2^$b, $n) Then $Test += $SuccessFlags[$b] Next $Results &= "0x" & Hex($Test,5) & @CRLF Next $Results = StringTrimRight($Results, 1) $nTimer = Round(TimerDiff($iTimer)/1000, 3) ConsoleWrite("$Results in " & $nTimer & "sec" & @LF & $Results & @LF) >_< Sweet! This is allot faster... now I just need to pick it apart to understand it. --- TTFN Link to comment Share on other sites More sharing options...
Malkey Posted September 11, 2008 Share Posted September 11, 2008 To enhance your example to make it more visual, added binary output. Global $BaseFlag = 512 Global $SuccessFlags[5] = [0x4, 0x10, 0x2000, 0x20000, 0x40000] $Results = "" $iTimer = TimerInit() For $n = 0 To (2 ^ 5) - 1 $Test = $BaseFlag For $b = 0 To 4 If BitAND(2 ^ $b, $n) Then $Test += $SuccessFlags[$b] Next $Results &= "0x" & Hex($Test, 5) & " = " & Hex2Bin("0x" & Hex($Test, 5)) & @CRLF Next ;$Results = StringTrimRight($Results, 1) $nTimer = Round(TimerDiff($iTimer) / 1000, 3) ConsoleWrite("$Results in " & $nTimer & "sec" & @LF & $Results) Func Hex2Bin($hex) Local $b = "" For $i = 1 To 32 $b = BitAND($hex, 1) & $b $hex = BitShift($hex, 1) Next Return $b EndFunc ;==>Hex2Bin Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now