Jump to content

How to convert Binary to 1s and 0s (string)?


Recommended Posts

I'm hoping to take a byte and convert it to its equivalent 8 digit 1s and 0s value as in

0x5 to 0101

Seems like a simple question but I haven't been able to find an answer anywhere ;)

I'm trying to make a tool to handle processor op-codes which are in 3 or 5 bit chunks.

For example, I need to read:

0x8683

convert it to:

1000011010000011

Then I can split it to process the op-code

100...001...10100...00011

..4 . &..1 . .. .r20 . . . .r3

Thanks!

Edited by EddieBoy
Link to comment
Share on other sites

A simple tip to convert any number to 1's and 0's:

For instance, you want to convert 21. Now do the following:

21/2 >> 10, remainder 1 (5th)

10/2 >> 5, remainder 0 (4th)

5/2 >> 2, remainder 1(3rd)

2/2 >> 1 (1st), remainder 0 (2nd)

The outcome is: 10101

Digit-wise arrangement shown in brackets.

----------------------------------------

:bye: Hey there, was I helpful?

----------------------------------------

My Current OS: Win8 PRO (64-bit); Current AutoIt Version: v3.3.8.1

Link to comment
Share on other sites

Try this

#include <String.au3>

ConsoleWrite(Integer2Binary(0x5) & @CRLF)
ConsoleWrite(Integer2Binary(0x8683) & @CRLF)

Func Integer2Binary($in)
    If $in = 0 Then Return 0
    Local $bin
    While $in > 0
        $bin &= Mod($in, 2)
        $in = Floor($in / 2)
    WEnd
    Return(_StringReverse($bin))
EndFunc

Br,

UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

@UEZ,

Something for the AutoIt Code Snippet thread?

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to comment
Share on other sites

@water: maybe, feel free to put it there ;)

@EddieBoy: have a look here: Might be useful for you.

Br,

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Ultra cool info MKISH!!

I came up with this clunker. but UEZ's looks much better. Thanks everyone, I can continue on now YAY!

;)

EDIT: UEZ, I checked into that thread and it's exactly the sort of situation I'm dealing with. I'll have to put my thinking cap on , but I think it will be quite helpful Thanks for that.

Func Hex2BinStr($hex)
$c = 0
$bin = ""
Do
$hex = $hex / 2
$bin = IsFloat($hex) & $bin
$hex = Floor($hex)
$c = $c + 1
Until $c = 16
Return $bin
EndFunc
Edited by EddieBoy
Link to comment
Share on other sites

Here is another one:

MsgBox(0, "", _BytesToBits(Binary("0x8683")))

Func _BytesToBits($bBinary)
    Local $byte, $bits="", $i, $j, $s
    For $i = 1 To BinaryLen($bBinary)
        $byte = BinaryMid($bBinary, $i, 1)
        For $j = 1 To 8
            $bits &= BitAND($byte, 1)
            $byte = BitShift($byte, 1)
        Next
    Next
    $s = StringSplit($bits, "")
    $bits = ""
    For $i = $s[0] To 1 Step -1
        $bits &= $s[$i]
    Next
    Return $bits
EndFunc

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Link to comment
Share on other sites

cant find (nor construct as of yet) the reverse of this, anyone have a Bits-to-Bytes?

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Link to comment
Share on other sites

This is the reverse of the earlier functions...

MsgBox(0,"",_BinToInt("10000100"))


Func _BinToInt($sValue)
    Local $iOut = 0, $aValue = StringSplit($sValue, "")
    For $i = 1 To $aValue[0]
        $aValue[0] -= 1
        If $aValue[$i] = "1" Then $iOut += 2 ^ ($aValue[0])
    Next
    Return Int($iOut)
EndFunc

Edit: Added Int() conversion of returned value. Hex() can now be applied directly to returned result for a BinToHex conversion.

Edited by Spiff59
Link to comment
Share on other sites

cant find (nor construct as of yet) the reverse of this, anyone have a Bits-to-Bytes?

Not pretty, but it should work. If the amount of bits is not a multiple of 8, 0s are appended. ("1" => 0x80)

Func _BitsToBytes($sBits)
    Local $bBytes = Binary(''), $iLen = StringLen($sBits)
    Local $iCnt = 0, $iVal = 0
    For $i = 1 To $iLen
        $iCnt += 1
        $iVal = BitShift($iVal, -1)
        If "1" = StringMid($sBits, $i, 1) Then
            $iVal = BitOR($iVal, 1)
        EndIf
        If $iCnt = 8 Then
            $iCnt = 0
            $bBytes &= BinaryMid($iVal, 1, 1)
            $iVal = 0
        EndIf
    Next
    If $iCnt Then $bBytes &= BinaryMid(Binary(BitShift($iVal, -8+$iCnt)), 1, 1)
    Return $bBytes
EndFunc
Edited by ProgAndy

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Link to comment
Share on other sites

Thanks for all the input guys. I think these questions are likely to come up for others too, so the info is great to have in one place.

I made a simple conversion tool to help with what I was doing. It's pretty much a dumbed down version of MKISH's excellent tool. It's not "idiot proofed" at all, and doesn't support hex values above 7FFFFFFF. I'll post it here in case it's useful to anyone else.

#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
GUICreate("Form1", 350, 250, 211, 182)
$Binary = GUICtrlCreateInput("", 16, 40, 320, 25)
GUICtrlSetFont(-1, 12, 400, 0, "Arial")
GUICtrlSetTip(-1, "Press 'Enter' to convert.")
GUICtrlSetLimit(-1, 32)
$Decimal = GUICtrlCreateInput("", -1, 115, -1, -1)
GUICtrlSetFont(-1, 12, 400, 0, "Arial")
GUICtrlSetTip(-1, "Press 'Enter' to convert.")
GUICtrlSetLimit(-1, 10)
$Hex = GUICtrlCreateInput("", -1, 196, -1, -1)
GUICtrlSetFont(-1, 12, 400, 0, "Arial")
GUICtrlSetTip(-1, "Press 'Enter' to convert.")
GUICtrlSetLimit(-1, 8)
GUICtrlCreateLabel(" BINARY", 130, 16, 200, -1)
GUICtrlSetFont(-1, 12, 400, 0, "Arial")
GUICtrlSetTip(-1, "Press 'Enter' to convert.")
GUICtrlCreateLabel("DECIMAL", -1, 92, 465, -1)
GUICtrlSetFont(-1, 12, 400, 0, "Arial")
GUICtrlSetTip(-1, "Press 'Enter' to convert.")
GUICtrlCreateLabel("   HEX", -1, 174, 465, -1)
GUICtrlSetFont(-1, 12, 400, 0, "Arial")
GUICtrlSetTip(-1, "Press 'Enter' to convert.")
GUISetState(@SW_SHOW)

While 1
$nMsg = GUIGetMsg()
Switch $nMsg
  Case $GUI_EVENT_CLOSE
   Exit
  Case $Binary
   GUICtrlSetData($Decimal, BinToDec(GUICtrlRead($Binary)))
   GUICtrlSetData($Hex, Hex(GUICtrlRead($Decimal)))
  Case $Decimal
   GUICtrlSetData($Hex, Hex(GUICtrlRead($Decimal)))
   GUICtrlSetData($Binary, ToBin(GUICtrlRead($Decimal)))
  Case $Hex
   GUICtrlSetData($Decimal, Dec(GUICtrlRead($Hex)))
   GUICtrlSetData($Binary, ToBin(GUICtrlRead($Hex)))
EndSwitch
WEnd

Func ToBin($Number)
If GUICtrlRead($Hex) = $Number Then
  $Number = Dec(Hex("0x" & $Number))
EndIf
$c = 0
$bin = ""
Do
  $Number = $Number / 2
  $bin = IsFloat($Number) & $bin
  $Number = Floor($Number)
  $c = $c + 1
Until $c = 32
Return $bin
EndFunc   ;==>ToBin

Func BinToDec($bin)
$bin = StringSplit($bin, "", 0);reads each bit into array
$Dec = 0
$x = 1
$n = $bin[0];checks length of array for ending the "Do"
Do
  If $bin[$n] = "1" Then ;if bit is a "1" then adds appropriate value to decimal
   $Dec = $Dec + $x
  EndIf
  $n = $n - 1 ;counts down to stop "Do" when at end of binary
  $x = $x * 2 ; raises bit value multiplyer for next loop
Until $n = 0 ;ends "Do" when "bits" end
Return $Dec
EndFunc   ;==>BinToDec
Edited by EddieBoy
Link to comment
Share on other sites

If you are going to write funtions that involve string manipulation, then I'm not sure what advantage there is to converting the data back and forth between binary and string var types. I imagine someone will disagree with me on this. Once all the string manipulation has finished, converting back to binary may have several advantages. I would be interested to hear your views.

I have generally used something like this (BTW code only accepts string input and does not recognise the prefix 0x):

Global Const $HEX_KEY[16][2] = [ _
["0","0000"],["1","0001"],["2","0010"],["3","0011"], _
["4","0100"],["5","0101"],["6","0110"],["7","0111"], _
["8","1000"],["9","1001"],["A","1010"],["B","1011"], _
["C","1100"],["D","1101"],["E","1110"],["F","1111"]]

Dim $sRet = "", $sString = "FEDCBA9876543210"

For $i = 1 To StringLen($sString)
    $sRet &= _BinaryString(StringMid($sString, $i, 1))
Next
MsgBox(0, "", $sRet)

$sString = $sRet
$sRet = ""
For $i = 1 To StringLen($sString) Step 4
    $sRet &= _HexString(StringMid($sString, $i, 4))
Next
MsgBox(0, "", $sRet)

Func _BinaryString($sHex)
    For $j = 0 To 15
        If $sHex = $HEX_KEY[$j][0] Then Return $HEX_KEY[$j][1]
    Next
EndFunc ;==> _BinaryString

Func _HexString($sBin)
    For $j = 0 To 15
        If $sBin = $HEX_KEY[$j][1] Then Return $HEX_KEY[$j][0]
    Next
EndFunc ;==> _HexString
Edited by czardas
Link to comment
Share on other sites

Two more examples of binary conversion functions.

Local $iNum = 0xEFFFFFF0

Local $sBin = _IntToBin($iNum)
Local $iInt = _BinToInt($sBin)

ConsoleWrite($iNum & @LF)
ConsoleWrite($sBin & @CRLF)
ConsoleWrite(StringRegExpReplace($sBin, "(.{8})", "1 ") & @LF)
ConsoleWrite($iInt & @LF)
ConsoleWrite("0x" & Hex($iInt) & @CRLF)

#cs
Returns:-
-268435472
11101111111111111111111111110000
11101111 11111111 11111111 11110000
-268435472
0xEFFFFFF0
#ce


Func _IntToBin($iInt)
    Local $b = ""
    For $i = 1 To 32
        $b = BitAND($iInt, 1) & $b
        $iInt = BitShift($iInt, 1)
    Next
    Return $b
EndFunc   ;==>_IntToBin

Func _BinToInt($bin)
    Local $aArr = StringSplit($bin, "", 2)
    Local $dec = 0
    For $i = UBound($aArr) - 1 To 0 Step -1
        If $aArr[$i] = "1" Then
            $dec = BitXOR($dec, BitShift(1, -(UBound($aArr) - 1 - $i)))
        EndIf
    Next
    Return $dec
EndFunc   ;==>_BinToInt
Edited by Malkey
Link to comment
Share on other sites

If you are going to write funtions that involve string manipulation, then I'm not sure what advantage there is to converting the data back and forth between binary and string var types.

I expect my use is uncommon, but I'm trying to make a "debug/tracer" for the MIPS processor machine language. Converting the data to a string is mainly as a human perceptual aid, but it is also an issue that MIPS functions use multiple chunks of odd number bytes (3 , 5 etc) to determine the functions- I find string data to be easier work with when I have to divide the bytes at odd intervals depending on the current op code. But I'm an ultra beginner so I may just be doing it the hard way ;)

Link to comment
Share on other sites

This is the reverse of the earlier functions...

MsgBox(0,"",_BinToInt("10000100"))


Func _BinToInt($sValue)
    Local $iOut = 0, $aValue = StringSplit($sValue, "")
    For $i = 1 To $aValue[0]
        $aValue[0] -= 1
        If $aValue[$i] = "1" Then $iOut += 2 ^ ($aValue[0])
    Next
    Return Int($iOut)
EndFunc
Edit: Added Int() conversion of returned value. Hex() can now be applied directly to returned result for a BinToHex conversion.
One variable less and without an if..then clause may also work:

#include <string.au3>

ConsoleWrite(_BinToInt("10000100") & @CRLF)

Func _BinToInt( $sValue)

   Local $iOut = 0
  
   $sValue = _StringReverse( $sValue)
   For $i = 1 to StringLen( $sValue)
       $iOut += StringMid( $sValue, $i, 1) * 2 ^ ($i-1)
   Next
   Return $iOut

EndFunc
Edited by qvex21

English is not my native language; please excuse typing errors.

Link to comment
Share on other sites

I'd considered a version without the If/Then using this line instead:

$iOut += $aValue[$i] * 2 ^ ($aValue[0])

It was no faster, so I went with the If/Then as I thought it was less complex, or more "self-documenting". It's really a case of 6-of-one, a half-dozen-of-the-other. I'm not sure I would like having a String() function within the loop itself though. The function might take a performance hit.

I do still find it interesting that any math using the exponent operator (^) forces the result to be a double whether it's necessary or not. That's why I stuck the Int() call onto the version above, just to simplify using the routine for a _BinToHex() conversion by simply running the result through one Hex() call. Hex() treats doubles a little differently than I'd of expected.

Edit: PS - Nice example!

Edited by Spiff59
Link to comment
Share on other sites

  • 5 years later...
On 04/05/2012 at 10:00 PM, Malkey said:

Two more examples of binary conversion functions.

 

Local $iNum = 0xEFFFFFF0

Local $sBin = _IntToBin($iNum)
Local $iInt = _BinToInt($sBin)

ConsoleWrite($iNum & @LF)
ConsoleWrite($sBin & @CRLF)
ConsoleWrite(StringRegExpReplace($sBin, "(.{8})", "1 ") & @LF)
ConsoleWrite($iInt & @LF)
ConsoleWrite("0x" & Hex($iInt) & @CRLF)

#cs
Returns:-
-268435472
11101111111111111111111111110000
11101111 11111111 11111111 11110000
-268435472
0xEFFFFFF0
#ce


Func _IntToBin($iInt)
    Local $b = ""
    For $i = 1 To 32
        $b = BitAND($iInt, 1) & $b
        $iInt = BitShift($iInt, 1)
    Next
    Return $b
EndFunc   ;==>_IntToBin

Func _BinToInt($bin)
    Local $aArr = StringSplit($bin, "", 2)
    Local $dec = 0
    For $i = UBound($aArr) - 1 To 0 Step -1
        If $aArr[$i] = "1" Then
            $dec = BitXOR($dec, BitShift(1, -(UBound($aArr) - 1 - $i)))
        EndIf
    Next
    Return $dec
EndFunc   ;==>_BinToInt

Would there be some regular expression for this?

Func Bin2Grafic($Bin,$Grafic="#")   
$Bin =StringReplace($Bin,"0"," ")
$Bin =StringReplace($Bin,"1",$Grafic)
Return $Bin
EndFunc
Func Grafic2Bin($Grafic)
    Local $Bit1,$Bin
    $Bit1=StringLeft( StringStripWS($Grafic,8),1)
    $Bin=StringReplace($Grafic," ","0") 
    $Bin=StringReplace($Bin,$Bit1,"1")
EndFunc

 

Link to comment
Share on other sites

PS: a small improvement

Func _IntToBin($iInt)
    Local $b = ""
    if IsBinary($iInt) Then
    For $i = 1 To 8
        $b = BitAND($iInt, 1) & $b
        $iInt = BitShift($iInt, 1)
    Next
    Else
    For $i = 1 To 32
        $b = BitAND($iInt, 1) & $b
        $iInt = BitShift($iInt, 1)
    Next
    EndIf
    Return $b
EndFunc   ;==>_IntToBin

 

Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...