binary

binary , a built-in Tcl routine, performs byte-oriented operations on values.

See Also

encoding
format
scan
base64, uuencode and zlib
For data data transfer encodings.
Working with binary data
ByteArrayObj
The Tcl C API for binary data operations.
Binary representation of numbers
About 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

Synopsis

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

Documentation

official reference

Description

binary is for working with byte strings -- values where each character has a code point of 255 or less. binary scan is used to extract data from such values, and binary format is used to generate such values. This is a sharp tool: If it encounters a character with a code point greater than 255, it simply ignores the extra bits, which can result in data loss if one isn't careful.

Examples

In a conversation in the Tcl Chatroom about how to display the bits in a number, DKF suggested this:

binary scan [binary format I $value] B32 x; set x

GPS: I use the following string to/from hexadecimal 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 code point, which is the same as the ascii value for a character, and the same as the iso8859-1 codepoint too, since unicode is a superset of ISO8859-1, which 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

PYK 2015-11-07: ::binary::^ might be the right name for a routine that does exclusive or operations on arbitrary strings. Here is an implementation of such a routine:

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::^]]