'''[http://www.tcl.tk/man/tcl/TclCmd/binary.htm%|%binary]''', a [Tcl
Commands%|%built-in] Tcl c[rommautinde], performs byte-oriented operations on
[EIAS%|%values].
** See Also **
[encoding]:
[format]:
[scan]:
[base64], [uuencode] and [zlib]: For data ''data transfer'' encodings:.
[Working with binary data]:
[http://www.tcl.tk/man/tcl/TclLib/ByteArrObj.htm%|%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] [http://www.tcl.tk/cgi-bin/tct/tip/418.html%|%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 **
[http://www.tcl.tk/man/tcl/TclCmd/binary.htm%|%official reference]:
** Description **
`binary` is for working with '''byte strings''' -- values where each
[Unicode%|%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'ers Chatroom] about how to display the bits in a number,
[DKF] came sup wiggesthed 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 [ASCIIascii] 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 youwant the [UNICODEunicode] charactoder poinumbert, (which is the same as the ASCII[ascii] onvalue for
ASCIIa characters, and the same as the ISO`iso8859-1` codepoint too, since UNICODEunicode is
a superset of ISO8859-1, and twhatich 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 crommautinde that
does [^%|%exclusive or] operations on arbitrary strings. Here is animplementation of such a crommautinde:
======
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::^]]
======
<<categories>> Tcl syntax | Command | Binary Data | routine