crashdemons Posted July 20, 2009 Share Posted July 20, 2009 (edited) I checked with Search but I didn't see anything too comprehensive. **These may not be useful to anyone, but I needed them. I needed some simple functions to:Fill out some operations that weren't providedBe able to read out numbers as bit strings (binary)Convert bit strings to numbersBe able to get/set specific bits in a value.Do some other obscure stuff with bitsNote:Be warned though, it seemed easiest to use BitShift and BitAnd to gain access to the Least Significant Bit - thus, many of these functions work as if the number was Little-Endian.This shouldn't be a major issue except causing confusion with inbuilt Bitwise operations (which I assume use Big-Endian) and using a reversed bit order for strings.To help combat the confusion, I included a parameter for Big-Endian on a couple functions.If you're thinking in terms of Big-Endian, this is all Right-to-Left.If you let me know about existing functions for something here, if there are, I will take a look.Code: (Includes function descriptions and a table of example outputs)expandcollapse popup;More Bitwise functions! ;AUTHOR: Crash Daemonicus ;INTRODUCTORY NOTES ; Except where noted, all functions here are little-endian and ; consider the Least-Significant-Bit to be the first/leftmost one. (and the zeroth bit index) ; thus, bit reading starts with the Least Significant as index 0 and continues to get More Significant as the bit index increases. ; WARNING: BitShift/etc appear to use Big-Endian. ; All "iBit" parameters are a 0-based bit index (little-endian) ; also, all "iLen" parameters are bit length values. ; extending past this, the phrase "subrange" refers to an amount of bits from a position, defined by a Start and End position, or alternatively Start and Length values. ; To get the same output as Windows Calc while using BitStr(...) you must set the BigEndian parameter to True or use BitReverse first. ; Windows Calc displays Big Endian bit strings that start with the first bit set to 1 as the Most-Significant-Bit and get Less-significant moving rightward. ;FUNCTIONS: ; BitStr - Returns a bit string with the a specified data size and endianness. ; StrBit - Returns the value of a bit string with a specified data size and endianness. ; BitGet - Returns the value of a specific bit index in an input number. ; BitSet - Returns the input number with the bit at a specified index set to a specified value. ; BitLen - Returns the minimum number of bits required to hold the input number. ; ------------------------------------------------------------------------------------------------- ; BitNAnd - Returns a BitNot'd BitAnd result of two input numbers. ; BitNOr - Returns a BitNot'd BitOr result of two input numbers. Checks if both bits are 0. ; BitXNOr - Returns a BitNot'd BitXOr result of two input numbers. Checks bit equivalence to each oter ; BitImp - Returns a number with a bit set to 1 when first input value implies the second - or rather, a BitOR result of Not(A) with B. ; ------------------------------------------------------------------------------------------------- ; BitLess - Returns a number with a bit set to 1 when the corresponding bit in the first input number is less than the second. (eg: 0,1 -> 1) ; BitTrim - Returns the input number with a specified number of bits at the beginning set to 0. ; BitMid - Returns a number representing a specific subrange of bits from the input value. ; BitReverse - Returns the input number with a specified subrange of bits in reverse order. ; BitIsolate - Returns the input number with all bits, except the specified subrange of bits, set to 0. ; BitAltNot - Returns the input number with NOT applied to alternating bits. ; BitChanged - Returns a number with a bit set to 1 where the corresponding bit in the input value differs from its preceding bit. ;EXAMPLES: ;--------------------------------------------------------------- ; Function Used | Input Value 1 (a) | Input Value 2 (b) ;--------------------------------------------------------------- ; | 170 | 240 ;--------------------------------------------------------------- ; BitStr(_, 16) | 0101010100000000 | 0000111100000000 ; BitStr(_, 8) | 01010101 | 00001111 ; BitStr(_, 4) | 0101 | 0000 ; BitGet(_, 1) | 1 | 0 ; BitSet(_, 3,1) | 01010101 | 00011111 ; BitSet(_, 3,0) | 01000101 | 00001111 ; BitNAnd(a,b) | 11111010 | ; BitNOr(a,b) | 10100000 | ; BitXNor(a,b) | 10100101 | ; BitImp(a,b) | 10101111 | ; BitImp(b,a) | 11110101 | ; BitLess(a,b) | 00001010 | ; BitLess(b,a) | 01010000 | ; BitTrim(_, 5) | 00000101 | 00000111 ; BitMid(_, 2,4) | 0101 | 0001 ; BitReverse(_,0,8)| 10101010 | 11110000 ; BitReverse(_,2,4)| 01101001 | 00110011 ; BitIsolate(_,2,4)| 00010100 | 00001100 ; BitAltNot(_) | 00000000 | 01011010 ; BitChanged(_) | 11111111 | 10001000 ;--------------------------------------------------------------- ; * Bit strings in this table are mostly 8-bit Little-Endian (reverse them to make any sense) ; Remember: The leftmost bit displayed here is the LEAST-SIGNIFICANT (smallest value) and the rightmost in a Big-Endian form. ;--------------------------------------------------------------- Func BitStr($n,$iLen=32,$BigEndian=False); in all likelyhood, you'll probably prefer *viewing* BigEndian bit strings. Local $s="",$start=0,$end=($iLen-1),$step=1 If $BigEndian Then $start=$end $end=0 $step=-1 EndIf For $i=$start To $end Step $step $s&=BitGet($n,$i) Next Return $s EndFunc Func StrBit($s,$iLen=32,$BigEndian=False); in all likelyhood, you'll probably prefer *viewing* BigEndian bit strings. Local $start=1, $end=StringLen($s), $step=1, $t=0, $p=0, $c If $end>$iLen Then $end=$iLen If $BigEndian Then $start=$end $end=1 $step=-1 EndIf For $i=$start To $end Step $step $c=StringMid($s,$i,1) If $c='b' Or $c=' ' Then ContinueLoop $t=BitSet($t,$p,Int($c)) $p+=1 Next Return $t EndFunc Func BitGet($n,$iBit=0) ;Gets the bit value at a specific 0-based bit index. (0=LSB) ; if n is input as 14 (1110b Big Endian) and iBit is input as 0 - 3, ; this would output 0, 1, 1, and 1 (Little Endian) Return BitAnd(BitShift($n,$iBit),1) EndFunc Func BitSet($n,$iBit=0,$Value=0) ;Sets the bit value at a specific 0-based bit index If $Value<>0 Then; we assume this is 1 Return BitOr($n,BitShift(1,-$iBit)) Else Return BitAnd($n,BitNot(BitShift(1,-$iBit))) EndIf EndFunc Func BitLen($n,$iMaxLen=32) If $n<0 Then Return $iMaxLen Local $i=0 While $n<>0 $n=BitShift($n,1) $i+=1 WEnd Return $i EndFunc ; Bit logic - check these (are we sure the parameters aren't BitNot()'d instead??) Func BitNAnd($n,$n2); could be called "BitNotBoth" Return BitNot(BitAnd($n,$n2)) EndFunc Func BitNOr($n,$n2); could also be called "BitIsZero" or "BitNeither", since it's only 1 when both compared bits are 0 Return BitNot(BitOR($n,$n2)) EndFunc Func BitXNOr($n,$n2); could be called "BitEqual", since its only 1 when both bits match. (thus XOR is "BitNotEqual") Return BitNot(BitXOR($n,$n2)); check this EndFunc Func BitImp($n,$n2) ; A implies B ;(Not A) Or (B) ;http://en.wikipedia.org/wiki/Material_conditional ;Note: for Converse Implication just use BitImp($n2,$n) ;Note2: same as a<=b (a [less than or equal to] b, which was formerly BitLessEqual. ) Return BitOR(BitNot($n),$n2) EndFunc ;more bit logic - order matters! Func BitLess($n,$n2) Local $t=0 For $i=0 To 31 If BitGet($n,$i)<BitGet($n2,$i) Then $t=BitSet($t,$i,1) Next Return $t EndFunc ;editing the values as if bits were characters in a string Func BitTrim($n,$iLen=1);sets a number of bits starting at the beginning(LSB) to 0 Return BitShift(BitShift($n,$iLen),-$iLen) EndFunc Func BitMid($n,$iBitStart,$iLen) ;retrieves a range of bits Return BitAND(BitShift($n,$iBitStart),BitNot(BitTrim(BitNot(0),$iLen))) EndFunc Func BitReverse($n,$iBitStart=0,$iLen=32) ;Returns a number with the selected subrange of bits reversed. Local $iBitEnd=$iBitStart+($iLen-1) Local $t=$n For $i=$iBitStart To $iBitEnd ;ConsoleWrite($i&':'&($iBitEnd-($i-$iBitStart))&' = '&BitGet($n,$iBitEnd-$i)&@CRLF) $t=BitSet($t,$i,BitGet($n,($iBitEnd-($i-$iBitStart)))) Next Return $t EndFunc ; really strange functions - this is like BitTrim, but for both sides of a selection Func BitIsolate($n,$iBitStart,$iLen) ; surrounds a subrange of bits with 0's, not changing the bits' position. Return BitAND($n,BitXor(BitTrim(BitNot(0),$iBitStart),BitTrim(BitNot(0),$iBitStart+$iLen))) EndFunc Func BitAltNot($n,$Evens=False) ; ? might be good for obfuscating numbers. ; applies NOT to alternating bits (eg: 000000000000 -> 1010101010...) ; If you apply this twice with the same parameters, the number reverts to the original value. Local $x=1 If $Evens Then $x+=1 For $i=0 To 31 If Mod($i+$x,2)=0 Then If BitGet($n,$i)=1 Then $n=BitSet($n,$i,0) Else $n=BitSet($n,$i,1) Endif EndIf Next Return $n EndFunc Func BitChanged($n) ; not sure what this is good for ;- returns a number with positions where the bit differed with the previous (bit 0 is always marked) Local $t=0,$b=-1,$bt For $i=0 To 31 $bt=BitGet($n,$i) If $bt<>$b Then $b=$bt $t=BitSet($t,$i,1) Endif Next Return $t EndFunc** (Frankly, I think more excerpt text needs to be included in Search results for context - but that's off-topic.) Edited July 20, 2009 by crashdemons My Projects - WindowDarken (Darken except the active window) Yahsmosis Chat Client (Discontinued) StarShooter Game (Red alert! All hands to battlestations!) YMSG Protocol Support (Discontinued) Circular Keyboard and OSK example. (aka Iris KB) Target Screensaver Drive Toolbar Thingy Rollup Pro (Minimize-to-Titlebar & More!) 2D Launcher physics example Ascii Screenshot AutoIt3 Quine Example ("Is a Quine" is a Quine.) USB Lock (Another system keydrive - with a toast.) Link to comment Share on other sites More sharing options...
Yashied Posted July 20, 2009 Share Posted July 20, 2009 It's a good idea. I also did this, but over time, came to the conclusion that native Bit...() functions, is sufficient for ANY operations + speed. My UDFs: iKey | FTP Uploader | Battery Checker | Boot Manager | Font Viewer | UDF Keyword Manager | Run Dialog Replacement | USBProtect | 3D Axis | Calculator | Sleep | iSwitcher | TM | NetHelper | File Types Manager | Control Viewer | SynFolders | DLL Helper Animated Tray Icons UDF Library | Hotkeys UDF Library | Hotkeys Input Control UDF Library | Caret Shape UDF Library | Context Help UDF Library | Most Recently Used List UDF Library | Icons UDF Library | FTP UDF Library | Script Communications UDF Library | Color Chooser UDF Library | Color Picker Control UDF Library | IPHelper (Vista/7) UDF Library | WinAPI Extended UDF Library | WinAPIVhd UDF Library | Icon Chooser UDF Library | Copy UDF Library | Restart UDF Library | Event Log UDF Library | NotifyBox UDF Library | Pop-up Windows UDF Library | TVExplorer UDF Library | GuiHotKey UDF Library | GuiSysLink UDF Library | Package UDF Library | Skin UDF Library | AITray UDF Library | RDC UDF Library Appropriate path | Button text color | Gaussian random numbers | Header's styles (Vista/7) | ICON resource enumeration | Menu & INI | Tabbed string size | Tab's skin | Pop-up circular menu | Progress Bar without animation (Vista/7) | Registry export | Registry path jumping | Unique hardware ID | Windows alignment More... Link to comment Share on other sites More sharing options...
Ascend4nt Posted July 20, 2009 Share Posted July 20, 2009 (edited) crashdemons, Interesting code tidbits.. I think there's a bunch of people that have already done Binary-base conversion or bit-operations. I myself did two base-conversions (in my sig), but I went for the full 64-bits (not supported yet by Bit*() functions unfortunately), and also created Assembly language versions using my _RemoteCodeExecution UDF... but hey, everyone gets to learn even if they are reinventing (parts of) the same wheel. Oh, and btw - the Bit*() functions work on numbers the same way everything else in x86 architecture works - Little Endian. It makes more sense to output strings in Big Endian format though. *edit:typo Edited July 20, 2009 by Ascend4nt My contributions: Performance Counters in Windows - Measure CPU, Disk, Network etc Performance | Network Interface Info, Statistics, and Traffic | CPU Multi-Processor Usage w/o Performance Counters | Disk and Device Read/Write Statistics | Atom Table Functions | Process, Thread, & DLL Functions UDFs | Process CPU Usage Trackers | PE File Overlay Extraction | A3X Script Extract | File + Process Imports/Exports Information | Windows Desktop Dimmer Shade | Spotlight + Focus GUI - Highlight and Dim for Eyestrain Relief | CrossHairs (FullScreen) | Rubber-Band Boxes using GUI's (_GUIBox) | GUI Fun! | IE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) | Magnifier (Vista+) Functions UDF | _DLLStructDisplay (Debug!) | _EnumChildWindows (controls etc) | _FileFindEx | _ClipGetHTML | _ClipPutHTML + ClipPutHyperlink | _FileGetShortcutEx | _FilePropertiesDialog | I/O Port Functions | File(s) Drag & Drop | _RunWithReducedPrivileges | _ShellExecuteWithReducedPrivileges | _WinAPI_GetSystemInfo | dotNETGetVersions | Drive(s) Power Status | _WinGetDesktopHandle | _StringParseParameters | Screensaver, Sleep, Desktop Lock Disable | Full-Screen Crash Recovery Wrappers/Modifications of others' contributions: _DOSWildcardsToPCRegEx (original code: RobSaunder's) | WinGetAltTabWinList (original: Authenticity) UDF's added support/programming to: _ExplorerWinGetSelectedItems | MIDIEx UDF (original code: eynstyne) (All personal code/wrappers centrally located at Ascend4nt's AutoIT Code) Link to comment Share on other sites More sharing options...
crashdemons Posted July 20, 2009 Author Share Posted July 20, 2009 (edited) Oh, and btw - the Bit*() functions work on numbers the same way everything else in x86 architecture works - Little Endian. Um yeah, except if you BitShift right a number by one bit you lose the Least Significant Bit. $n=BitShift(BitShift(3,1),-1); should now be 2 if we lost the LSB MsgBox(0,"",$n) So, if we assume the LSB is on the right and the MSB is on the left - and if we read left to right - then the Most Significant Bit is being read first - making this Big Endian, no? Also, if that weren't enough, the binary text in the examples for the help file reflect Big Endian values. Although, perhaps you meant Little Endian is ultimately used at some level, but it doesn't seem to be made apparent in either form or feature here. ------------------------------------------ However, I don't think this is a dead-end topic because there are more complicated Bit operations that could be added to this - I just can't think of any at the moment. And while I know that doing these in AutoIt has a sacrifice to speed, but what else are you going to do to get the nth bit? @Yashied - why in the world did you need a for loop in _SetBit and _GetBit ? perhaps not relying on loops might have increased your efficiency. Some of my functions loop, but BitGet and BitSet do not (single bits), also - BitMid (which can be used to get a range of bits) does not loop either. Have a look. As for the ones that do use loops, I'd love to remove their loops, if it is possible. Edited July 20, 2009 by crashdemons My Projects - WindowDarken (Darken except the active window) Yahsmosis Chat Client (Discontinued) StarShooter Game (Red alert! All hands to battlestations!) YMSG Protocol Support (Discontinued) Circular Keyboard and OSK example. (aka Iris KB) Target Screensaver Drive Toolbar Thingy Rollup Pro (Minimize-to-Titlebar & More!) 2D Launcher physics example Ascii Screenshot AutoIt3 Quine Example ("Is a Quine" is a Quine.) USB Lock (Another system keydrive - with a toast.) Link to comment Share on other sites More sharing options...
Ascend4nt Posted July 20, 2009 Share Posted July 20, 2009 Um yeah, except if you BitShift right a number by one bit you lose the Least Significant Bit. $n=BitShift(BitShift(3,1),-1); should now be 2 if we lost the LSB MsgBox(0,"",$n) So, if we assume the LSB is on the right and the MSB is on the left - and if we read left to right - then the Most Significant Bit is being read first - making this Big Endian, no? Also, if that weren't enough, the binary text in the examples for the help file reflect Big Endian values. crashdemons, Okay, I see where the confusion is. BitShift left/right is confusing in that the terminology used, even at the Assembly level, talks about 'right' being towards the least significant bit, and 'left' towards the most significant bit. There's more bit movement operations that refer to shifting/scanning/rotating bits left or right, but you have to think of the number as a 'whole' at that point. On a 'byte' level, it would be correct, because individual bytes are stored in 'Big Endian bit form'... its just when you go to multi-byte operations (16-bit, 32-bit, 64-bit etc), that the 'Little-Endianess' comes into play, because Endianess really refers to bytes, not bits. So hex # AB CD (2 bytes) is stored as CD AB in memory, not DC BA, as would a 32-bit # of 09 AB CD EF (stored as EF CD AB 09). You can see this for yourself by doing this: MsgBox(0,"",Binary(0x09ABCDEF)) Binary takes the number and breaks it down into a byte-by-byte operation. That's the best way to see how Endianess works on the Intel platform.. Does that help any? My contributions: Performance Counters in Windows - Measure CPU, Disk, Network etc Performance | Network Interface Info, Statistics, and Traffic | CPU Multi-Processor Usage w/o Performance Counters | Disk and Device Read/Write Statistics | Atom Table Functions | Process, Thread, & DLL Functions UDFs | Process CPU Usage Trackers | PE File Overlay Extraction | A3X Script Extract | File + Process Imports/Exports Information | Windows Desktop Dimmer Shade | Spotlight + Focus GUI - Highlight and Dim for Eyestrain Relief | CrossHairs (FullScreen) | Rubber-Band Boxes using GUI's (_GUIBox) | GUI Fun! | IE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) | Magnifier (Vista+) Functions UDF | _DLLStructDisplay (Debug!) | _EnumChildWindows (controls etc) | _FileFindEx | _ClipGetHTML | _ClipPutHTML + ClipPutHyperlink | _FileGetShortcutEx | _FilePropertiesDialog | I/O Port Functions | File(s) Drag & Drop | _RunWithReducedPrivileges | _ShellExecuteWithReducedPrivileges | _WinAPI_GetSystemInfo | dotNETGetVersions | Drive(s) Power Status | _WinGetDesktopHandle | _StringParseParameters | Screensaver, Sleep, Desktop Lock Disable | Full-Screen Crash Recovery Wrappers/Modifications of others' contributions: _DOSWildcardsToPCRegEx (original code: RobSaunder's) | WinGetAltTabWinList (original: Authenticity) UDF's added support/programming to: _ExplorerWinGetSelectedItems | MIDIEx UDF (original code: eynstyne) (All personal code/wrappers centrally located at Ascend4nt's AutoIT Code) 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