Updated 2015-11-08 00:46:29 by pooryorick

binary, a built-in Tcl command, performs conversions on the bytes in a string, rather than the characters.

Synopsis  edit

binary format formatString ?arg arg ...?
binary scan string formatString ?varName varName ...?
binary encode format ?-option value ...? data
binary decode format ?-option value ...? data

Documentation  edit

official reference

Description  edit

binary facilitates the direct manipulation of bytes in a string, and can interpret those bytes in various ways. binary scan is used to extract data, and binary format is used to generate data.

Examples  edit

In a conversation in the Tcl'ers Chat about how to display the bits in a number DKF came up with this:
binary scan [binary format I $value] B32 x; set x

GPS: I use the following string to/from hex conversion procedures to store files that may contain special characters that interfere with the OS filesystem in my Grindweb program:
proc convert.string.to.hex str {
    binary scan $str H* hex
    return $hex
}

proc convert.hex.to.string hex {
    foreach c [split $hex {}] {
        if {![string is xdigit $c]} {
            return "#invalid $hex"
        }
    }
    binary format H* $hex
}

Displaying the ASCII equivalent of characters in a string:
set chrs abc
binary scan [encoding convertto ascii $chrs] c* x
puts $x
97 98 99

results in the translation of the characters to hex being assigned to $x. If the characters are some encoding other than ASCII, just change the ascii to the appropriate encoding name.

DKF: Also consider using scan $str %c for single characters where you want the UNICODE character number (which is the same as the ASCII one for ASCII characters, and the same as the ISO8859-1 codepoint too, since UNICODE is a superset of ISO8859-1 and that in turn is a superset of ASCII).

AMG: Here's a way to reverse the bit order of each eight-bit character in a string:
proc bit_reverse {str} {
    binary scan $str B* bits
    binary format b* $bits
}

Bitwise Exclusive Or  edit

PYK 2015-11-07: ::binary::^ might be the right name for a command that does exclusive or operations on arbitrary strings. Here is an implementation of such a command:
proc ::tcl::binary::^ {t1 t2} {
   if {$t2 < $t1} {
      set t1 $t2[set t2 $t1; list]
   }
   set step 256
   set res {}
   for {set i 0} {$i < [string length $t1]} {incr i $step} {
      set end [expr {min($i+$step-1, [string length $t1]-1)}]
      binary scan [string range $t1 $i $end] c* codes1
      binary scan [string range $t2 $i $end] c* codes2
      foreach c1 $codes1 c2 $codes2 {
         if {$c1 eq {} || $c2 eq {}} {
            break
         }
         append res [binary format c [::tcl::mathop::^ $c1 $c2]]
      }
   }
   return $res
}

namespace ensemble configure ::binary -map [dict merge [
   namespace ensemble configure ::binary -map] [
      dict create ^ ::tcl::binary::^]]

See Also  edit

encoding
format
scan
base64, uuencode and zlib
For transfer encodings:
Working with binary data
ByteArrayObj
The Tcl C API for binary data operations.
Binary representation of numbers
converting to and from the textual binary representation of numbers
bitstrings
another facility for working with binary data
TIP 418, Add binary Subcommands for In-Place Modification