Jump to content

binary to octal


Recommended Posts

Hi,

I have a binary string that I want to convert to octal, The string I want to convert is,

10001001010100000100111001000111000011010000101000011010

 

The String is read from a .txt file

Once its converted it should read this,

4   2   2   5   0   1   1   6   2   1   6   0   6   4   1   2   0   6   10

which I want written to the .txt file to overwrite the original binary string.

The 10 at the end should be ignored as there are not 3 digits to convert.

I'm thinking it should read the string from left to right to get the next 3 digits before converting them to its oct value. would this be the best way to do this or is there a better way?

If i'm on the right track can anyone give me an example of how to write this script please?

I've looked at the StringLeft function & StringReplace but I'm not sure how to use them the correct way to accomplish what I'm trying to do.

Thanks

 

Link to comment
Share on other sites

Try this:

;coded by UEZ build 2016-05-06
Global $sBin = "10001001010100000100111001000111000011010000101000011010"

Global $sOctal = Convert_Bin_To_Oct(StringTrimRight($sBin, Mod(StringLen($sBin), 3)))
Global $sRest = StringRight($sBin, Mod(StringLen($sBin), 3))

MsgBox(0, "", $sOctal & ", " & $sRest)

Func Convert_Bin_To_Oct($sBin)
    $sBin = StringStripWS($sBin, 8)
    If StringRegExp($sBin, "[^0-1]", 0) Then Return SetError(1, 0, -1) ;not binary
    Local $aFillUp[3] = ["", "00", "0"], $i, $sOctal
    Local $aTokens = StringRegExp($aFillUp[Mod(StringLen($sBin), 3)] & $sBin, ".{3}", 3)
    For $i = 0 To UBound($aTokens) - 1
        $sOctal &= StringLeft($aTokens[$i], 1) * 2^2 + StringMid($aTokens[$i], 2, 1) * 2^1 + StringRight($aTokens[$i], 1) * 2^0 & " "
    Next
    Return $sOctal
EndFunc

 

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

56 minutes ago, UEZ said:

Try this:

Global $sBin = "10001001010100000100111001000111000011010000101000011011"

Global $sOctal = Convert_Bin_To_Oct($sBin)

MsgBox(0, "", $sOctal)

Func Convert_Bin_To_Oct($sBin)
    $sBin = StringStripWS($sBin, 8)
    If StringRegExp($sBin, "[^0-1]", 0) Then Return SetError(1, 0, -1) ;not binary
    Local $aFillUp[3] = ["", "00", "0"], $i, $j, $sOctal
    Local $aTokens = StringRegExp($aFillUp[Mod(StringLen($sBin), 3)] & $sBin, ".{3}", 3)
    For $i = 0 To UBound($aTokens) - 1
        $sOctal &= StringLeft($aTokens[$i], 1) * 2^2 + StringMid($aTokens[$i], 2, 1) * 2^1 + StringRight($aTokens[$i], 1) * 2^0 & " "
    Next
    Return $sOctal
EndFunc

 

 

@UEZ Your function gives a wrong result!


@am632 Try this:

Global $sBinary = "10001001010100000100111001000111000011010000101000011011" ;"10001001"

Global $sOctal = _BinaryToDec($sBinary)

ConsoleWrite($sBinary & " = " & $sOctal & @CRLF)
ConsoleWrite($sBinary & " ~ " & Int($sOctal) & @CRLF)

MsgBox(0, "Bin2Dec", $sBinary & @CRLF & " = " & $sOctal & @CRLF & " ~ " & Int($sOctal))

Func _BinaryToDec($sBinary)
    $sBinary = StringStripWS($sBinary, 8)
    Local $xOutput = 0, $intIndex
    If StringRegExp($sBinary, '[0-1]') Then
        For $intIndex = StringLen($sBinary) To 1 Step -1
            $strDigit = StringMid($sBinary, $intIndex, 1)
            Switch $strDigit
                Case 0
                    ContinueLoop
                Case 1
                    $xOutput = $xOutput + (2 ^ (StringLen($sBinary) - $intIndex))
                Case Else
                    ; invalid binary digit, so the whole thing is invalid
                    Return SetError(1, 0, "")
            EndSwitch
        Next
        Return $xOutput
    Else
        Return SetError(1, 0, "")
    EndIf
EndFunc   ;==>_BinaryToDec

 

Regards,
 

Link to comment
Share on other sites

Simpler, but with little conformal checking:

Global $sBin = "10001001010100000100111001000111000011010000101000011010"
Global $sOctal = Convert_Bin_To_Otc($sBin)
MsgBox(0, "", $sOctal)

Func Convert_Bin_To_Otc($sBin)
    Local $sBinOct = "000 001 010 011 100 101 110 111"
    Local $sOctal
    Local $aTokens = StringRegExp($sBin, "[01]{3}|[01]{1,2}$", 3)
    For $i = 0 To UBound($aTokens) - 1
        $sOctal &= (StringLen($aTokens[$i]) = 3 ? (StringInStr($sBinOct, $aTokens[$i]) - 1) / 4 : $aTokens[$i]) & " "
    Next
    Return StringTrimRight($sOctal, 1)
EndFunc

 

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

10 hours ago, Trong said:

@UEZ Your function gives a wrong result!

Are you sure? ;)

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

My three cents, without a lookup table:

Global $sBin = "10001001010100000100111001000111000011010000101000011011"
MsgBox(0, "Bin2Oct",_Bin2Oct($sBin))

Func _Bin2Oct($sBin)

    $sBin=StringStripWS($sBin,8)
    If StringRegExp($sBin,"[^0-1]",0) or Stringlen($sBin)=0 Then Return SetError(1,0,-1) ; not binary

    Local $oct,$sOctal=""
    For $cc=0 to Int(stringlen($sbin)/3)-1  ; clips trailing bits
        $oct=Number("0x" & stringmid($sbin,1+$cc*3,3))
        $sOctal&=BitShift($oct,6)+BitShift(BitAND(0x010,$oct),3)+BitAND(0x001,$oct)
    Next

    Return $sOctal
EndFunc

This discards any trailing bits,, which in my view should not be part of the conversion proper. The OP can append them with: 

_Bin2Oct($sBin) & StringRight($sBin,Mod(StringLen($sBin),3))

I would myself probably opt to prefix the bit string with leading zeroes in the function:

$sBin = StringLeft("00",Mod(StringLen(StringStripWS($sBin,8)),3)) & StringStripWS($sBin,8)

but that's not what the OP wanted.

Edited by RTFC
Link to comment
Share on other sites

Hi guys,

Thanks for all the examples, really appreciate it.

I'm favouring jchd's example for this as it doesn't display the comma before the 10, how would I be able to not have any spaces in the octal string though (I know there were spaces in my original post but this was just for clarity of reading soz)?

I'll be honest I really dont understand how the code works - I keep reading through it but I havent used some of these functions before so it's not obvious to me. Would it be possible to write a function to put it back to a binary string again? I would normally have a go myself first to at least try but I really don't get it right now.

Thanks for all the help.

am

Link to comment
Share on other sites

Just ask:

Global $sBin = "10001001010100000100111001000111000011010000101000011010"
Global $sOctal = Convert_Bin_To_Otc($sBin)
MsgBox(0, "", $sOctal)

Func Convert_Bin_To_Otc($sBin)
    Local $sBinOct = "000 001 010 011 100 101 110 111"
    Local $sOctal
    Local $aTokens = StringRegExp($sBin, "[01]{3}|[01]{1,2}$", 3)
    For $i = 0 To UBound($aTokens) - 1
        $sOctal &= StringLen($aTokens[$i]) = 3 ? (StringInStr($sBinOct, $aTokens[$i]) - 1) / 4 : $aTokens[$i]
    Next
    Return $sOctal
EndFunc

Just be aware that you don't have any way to determine if the last 1 or 2 digits in {0.1} are actual octal digit(s) or the remnant of the uncomplete string of binary digits.

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

Hi,

Thanks for that, thats exactly what I wanted, I get what you're saying about the left over digits but it shouldn't matter for my needs, I assume the left over digits would also be ignored when converted back to binary or would this not be the case? I'm simply trying to shorten a particular string of characters which I can un-shorten later.

Would you be able to show me how i'd go about changing it back into its binary string value please?

Thanks a lot

am

Link to comment
Share on other sites

That won't work: if the input string length is not a multiple of 3, then the remaining digits need to be separated somehow, else they will be interpreted as octal. If it's just for shortening, why use octal? Larger bases wil shrink the data more efficiently.

Yet I wonder where the string of binary digits come from. This doesn't look efficient in the first place.

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

ok, would it be possible to check if the string is devisable by 3 first and store any remaining characters in a variable before removing them?

The binary string in the example is not the whole string im using, just a shortend string for the sake of the example.

I know there are other bases that will shring the string more but I just want to stick to a base with numbers, and as far as im aware octal offeres the best solution for this.

Link to comment
Share on other sites

Isn't decimal a base with "numbers"?

If you want to stick with octal, then you can use a smart trick to store the 1 or 2 last digits in the same string and not heve them misinterpreted back: add 8 to the last digit or 88 to the value formed by the last 2 digits. When you read your "cooked octal" string any (last) digit > 7 will denote the remnant of initial binary. And all this within 0..9 without extra tax.

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

If you want to follw the last route, try this:

Global $sBin = "10001001010100000100111001000111000011010000101000011010"
Global $sOctal = _BinaryStringToOctalString($sBin)
MsgBox(0, "To octal", $sBin & @LF & $sOctal)
MsgBox(0, "From octal", $sBin & @LF & OctalStringToBinaryString($sOctal))

Func _BinaryStringToOctalString($sBin)
    Local $sBinOct = "000 001 010 011 100 101 110 111"
    Local $sOctal
    Local $aTokens = StringRegExp($sBin, "[01]{3}|[01]{1,2}$", 3)
    For $i = 0 To UBound($aTokens) - 1
        $sOctal &= StringLen($aTokens[$i]) = 3 ? (StringInStr($sBinOct, $aTokens[$i]) - 1) / 4 : $aTokens[$i] + 88
    Next
    Return $sOctal
EndFunc

Func OctalStringToBinaryString($sOctal)
    Local $sBinOct = "000001010011100101110111"
    Local $sBinary
    Local $aDigits = StringSplit($sOctal, '', 2)
    For $i = 0 To UBound($aDigits) - 1
        $sBinary &= $aDigits[$i] < '8' ? StringMid($sBinOct, 3 * $aDigits[$i] + 1, 3) : $aDigits[$i] - 8
    Next
    Return $sBinary
EndFunc

 

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

SPAM :P

@jchd you can create a function to convert text into binary and vice versa?

Global $sBin = "10001001010100000100111001000111"

MsgBox(0, "Bin2Str", "Binary IN: " & $sBin & @LF & "String OUT: ‰PNG")
MsgBox(0, "Str2Bin", "String IN: ‰PNG" & @LF & "Binary OUT: " & $sBin)

Func _BinaryToString($sBin)

EndFunc   ;==>_BinaryToString

Func _StringToBinary($sString)

EndFunc   ;==>_StringToBinary

 

Edited by Trong

Regards,
 

Link to comment
Share on other sites

24 minutes ago, jchd said:

If you want to follw the last route, try this:

Global $sBin = "10001001010100000100111001000111000011010000101000011010"
Global $sOctal = _BinaryStringToOctalString($sBin)
MsgBox(0, "To octal", $sBin & @LF & $sOctal)
MsgBox(0, "From octal", $sBin & @LF & OctalStringToBinaryString($sOctal))

Func _BinaryStringToOctalString($sBin)
    Local $sBinOct = "000 001 010 011 100 101 110 111"
    Local $sOctal
    Local $aTokens = StringRegExp($sBin, "[01]{3}|[01]{1,2}$", 3)
    For $i = 0 To UBound($aTokens) - 1
        $sOctal &= StringLen($aTokens[$i]) = 3 ? (StringInStr($sBinOct, $aTokens[$i]) - 1) / 4 : $aTokens[$i] + 88
    Next
    Return $sOctal
EndFunc

Func OctalStringToBinaryString($sOctal)
    Local $sBinOct = "000001010011100101110111"
    Local $sBinary
    Local $aDigits = StringSplit($sOctal, '', 2)
    For $i = 0 To UBound($aDigits) - 1
        $sBinary &= $aDigits[$i] < '8' ? StringMid($sBinOct, 3 * $aDigits[$i] + 1, 3) : $aDigits[$i] - 8
    Next
    Return $sBinary
EndFunc

 

This seems to do the job perfectly, Thanks for all the help.

:)

Link to comment
Share on other sites

40 minutes ago, Trong said:

SPAM :P

@jchd you can create a function to convert text into binary and vice versa?

Global $sBin = "10001001010100000100111001000111000011010000101000011010"

MsgBox(0, "To octal", "Binary IN: " & $sBin & @LF & "String OUT: ?PNG")
MsgBox(0, "To octal", "String IN: ?PNG" & @LF & "Binary OUT: " & $sBin)

Func _BinaryToString($sBin)

EndFunc   ;==>_BinaryToString

Func _StringToBinary($sString)

EndFunc   ;==>_StringToBinary

 

The binary is wrong (at least in Windows Western codepage).

;1000 1001  0101 0000  0100 1110  0100 0111  0000 1101  0000 1010  0001 1010
; 8    9     5    0     4    E     4    7     0    D     0    A     1    A
;    ‰          P          N          G         CR         LF        SUB

Also remember that what you call text is, in AutoIt, Unicode as UTF16-LE (more precisely it's UCS2, but anyway).

Why are strings of binary digits so fashionable today? It that a new social media challenge or what?

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

In ASCII conversion table in my computer books: character, HEX and binary code.
Convert STRING to HEX is simple in AutoIt, but I could not find a function to convert binary to string and string to binary.

 I also do not understand why AutoIt called binary string is Hex: BinaryToString() and StringToBinary().

 Why does not the HexToString() and StringToHex()?

I was stupid again?

Regards,
 

Link to comment
Share on other sites

Simple: it's never useful to manipulate a string of ASCII 0s and 1s. The most compact representation low-level in common use is hexadecimal. A binary variant (= datatype) in AutoIt and every language I know of essentially means "series of bytes with no possible interpretation as text or number".

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

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

×
×
  • Create New...