deterministic context-independent focus-independent

Returns binary data as a sequence of integer octets.

If $value is a then the empty sequence is returned.

Octets are returned in sequence, as instances of xs:unsignedByte (integers ranging from 0 to 255).

bin:to-octets(bin:hex('1122AAFF') 17, 34, 170, 255 bin:to-octets(bin:hex('')) ()

The result type is changed from xs:integer to xs:unsignedByte. This is made possible by the more liberal coercion rules defined in XPath 4.0.

deterministic context-independent focus-independent

Converts a sequence of octets into binary data.

Octets are integers from 0 to 255.

If $values is the empty sequence, the function returns a binary value.

bin:from-octets((17, 34, 170, 255)) bin:hex('1122AAFF') bin:from-octets(()) bin:hex('')

The argument type is changed from xs:integer to xs:unsignedByte. This is made possible by the more liberal coercion rules defined in XPath 4.0. A consequence of the change is that supplying an out-of-range integer value is now a type error with the standard error code XPTY0004, rather than the custom error code bin:octet-out-of-range previously used.

deterministic context-independent focus-independent

Constructs a binary value from a string of hexadecimal digits ([0-9A-Fa-f]*).

If $value is the empty sequence, the function returns an empty sequence.

Any whitespace and underscore characters are stripped from $value.

If the length of of the resulting string is an odd number, then a single "0" digit is prepended to the value, so that it contains an even number of hexadecimal digits.

The resulting string is then cast to type xs:hexBinary, which is then cast to xs:base64Binary.

$value ! ( replace(., '[_\s]', '') -> concat(if (string-length(.) mod 2 eq 1) { "0" }, .) -> xs:hexBinary(.) -> xs:base64Binary(.) )

is raised if $value cannot be parsed as a hexadecimal number.

The order of octets in the result follows the order of characters in the string.

If $value is an empty string, the result will be a xs:base64Binary value.

When the input string has an even number of characters, this function delivers the same result as the expression xs:base64Binary(xs:hexBinary($string)).

bin:hex('1122_3F4E') xs:base64Binary("ESI/Tg==") bin:hex('122 3F4E') xs:base64Binary("ASI/Tg==")

The input string is now allowed to include embedded underscores and whitespace.

deterministic context-independent focus-independent

Constructs a binary value from a string of zeroes and ones ([01]*)

If $value is the empty sequence, the function returns an empty sequence.

Any whitespace and underscore characters are stripped from $value.

As many zero digits (U+0030) as necessary are prepended to $value to make its string length a multiple of 8.

The string is then partitioned into substrings of length 8, and each such substring B is converted to an integer in the range 0 to 255 by applying the function fn:parse-integer(B, 2). The resulting sequence of integers is then converted to a by applying the function bin:from-octets.

$value ! ( (: process input if present, otherwise return () :) (: strip underscores and whitespace :) replace(., '[_\s]', '') (: extend to a multiple of 8 binary digits :) -> concat(replicate("0", 7 - (string-length(.) - 1) mod 8), .) (: insert a separator after every 8 digits :) -> replace(., "(.{8})", "$1/") (: split into groups of 8 digits :) -> tokenize(., "/")[.] (: parse each group of 8 binary digits as a radix-2 integer :) ! parse-integer(., 2) (: construct a binary value from these octets :) -> bin:from-octets(.) )

is raised if $value cannot be parsed as a binary number.

The order of octets in the result follows the order of characters in the string.

If $value is an empty string, the result will be a xs:base64Binary value.

bin:bin('1101_0001_1101_0101') bin:hex("D1D5") bin:bin('1 0001 1101 0101') bin:hex("11D5") bin:bin(' 101 ') bin:hex("05")

The input string is now allowed to include embedded underscores and whitespace.

deterministic context-independent focus-independent

Constructs a binary value from a string of octal digits ([0-7]*)

If $value is the empty sequence, the function returns an empty sequence.

Otherwise:

Any whitespace and underscore characters are stripped from $value.

Each octal digit in $value is replaced by its binary equivalent ("0""000", "1""001", "2""010", "3""011", "4""100", "5""101", "6""110", "7""111").

A maximum of two leading zero digits are stripped.

The resulting string is converted to a by applying the function bin:bin to the result.

The order of octets in the result follows the order of characters in the string.

$value ! ( replace(., '[_\s]', '') => characters() =!> { "0": "000", "1": "001", "2": "010", "3": "011", "4": "100", "5": "101", "6": "110", "7": "111" }() =!> replace("^0?0?", "") => string-join() => bin:bin() )

is raised if $value cannot be parsed as an octal number.

The order of octets in the result follows the order of characters in the string.

If $value is a zero-length string, the result will be a xs:base64Binary value.

The rule for padding to a whole number of octets ensures that leading zeroes are significant in determining the length of the final binary value, while also allowing a value of any length to be constructed. For example (underscores added for readability):

An input of "0" translates first to the string "000"; two leading zeroes are removed producing "0", which bin:bin converts to bin:hex("00").

An input of "155" translates to the binary string "001_101_101". The first two zeroes are removed, and bin:bin converts the result to bin:hex("6D")

An input of "355" translates to the binary string "011_101_101". The first zero is removed, and bin:bin converts the result to bin:hex("ED").

An input of "555" translates to the string "101_101_101", which bin:bin converts to bin:hex("016D").

An input of "0155" translates to the string "000_001_101_101". The first two zeroes are stripped giving "0_001_101_101", which bin:bin converts to bin:hex("006D").

The result of the expression bin:octal("177 177 177 177") is the 5-octet value bin:hex("03 F9 FC FE 7F") and not (as some users might imagine) the 4-octet value bin:hex("7F 7F 7F 7F"). To achieve the latter result, the expression $value => tokenize() => bin:octal() => bin:join() can be used.

bin:octal('') bin:hex('') bin:octal('0') bin:hex('00') bin:octal('377') bin:hex('FF') bin:octal('777') bin:hex('01FF') bin:octal('0377') bin:hex('00FF') bin:octal('11_223_047') bin:hex('252627')

The input string is now allowed to include embedded underscores and whitespace.

The way in which the value is adjusted to a whole number of octets has been clarified. The rules have been made more precise, and might not match the interpretation adopted by existing implementations.

deterministic context-independent focus-independent

Selects a specified range of octets from a binary value.

If the value of $value is the empty sequence, the function returns an empty sequence.

Otherwise, the function returns a section of binary data starting at $offset. The offset is zero-based. If $size is present and non-empty, the size of the returned binary data is $size octets. If $size is absent or empty, all remaining data from $offset is returned.

The $offset is zero based.

The values of $offset and $size must be non-negative integers.

It is a dynamic error if $offset + $size is larger than the size of the binary data in $value.

$value => bin:to-octets() => subsequence($offset + 1, $size) => bin:from-octets()

is raised if $offset is negative or $offset + $size is larger than the size of the binary data of $value.

is raised if $size is negative.

The function differs in several ways from fn:subsequence and fn:substring:

The $offset and $size are supplied as integers, not doubles.

The $offset is zero-based, not one-based.

An error is raised if the selection goes outside the bounds of the value.

bin:part(bin:hex('11223344556677'), 0, 4) bin:hex('11223344') bin:part(bin:hex('11223344556677'), 4) bin:hex('556677') bin:part(bin:hex('11223344556677'), 7) bin:hex('') bin:part(bin:hex('11223344556677'), 5, 0) bin:hex('')

This example tests whether $data starts with binary content consistent with a PDF file:

bin:part($data, 0, 4) eq bin:hex("25504446")

25504446 is the magic number for PDF files: it is the hexadecimal representation of the result of encoding the string "%PDF" in UTF-8 (or US-ASCII). Note that the function bin:encode-string can be used to convert a string to its binary representation.

deterministic context-independent focus-independent

Inserts octets at a given point in a binary value.

If the value of $value is the empty sequence, the function returns an empty sequence.

If the value of $extra is the empty sequence, the function returns $value.

Otherwise, the function returns a binary value formed by concatenating the bin:part($value, 0, $offset), then $extra, then bin:part($value, $offset) $extra, and then the remaining data from $value.

The $offset is zero based, and must be non-negative.

$value => bin:to-octets() => insert-before($offset + 1, bin:to-octets($extra)) => bin:from-octets()

is raised if $offset is negative or $offset is larger than the size of the binary data of $value.

If $offset is zero, the result is the binary concatenation of $extra and $value.

bin:insert-before(bin:hex('FFFF'), 1, bin:hex('00')) bin:hex('FF00FF') bin:insert-before(bin:hex('FFFF'), 0, bin:hex('00')) bin:hex('00FFFF') bin:insert-before(bin:hex('FFFF'), 2, bin:hex('00')) bin:hex('FFFF00')
deterministic context-independent focus-independent

Returns the size of a binary value, measured in octets.

Returns the number of octets in the binary value $value.

count(bin:to-octets($value)) bin:length(bin:hex('FFFF')) 2 bin:length(bin:hex('')) 0
deterministic context-independent focus-independent

Concatenates a sequence of binary values in order.

The function returns an xs:base64Binary value created by concatenating the binary values in the sequence $values, in order.

$values =!> bin:to-octets() => bin:from-octets()

If $values is the empty sequence, the function returns a binary value.

bin:join((bin:hex('0000'), bin:hex('FFFF'), bin:hex('0000')) bin:hex('0000FFFF0000') bin:join(()) bin:hex('') bin:join( (1 to 4) ! bin:hex('F0') ) bin:hex('F0F0F0F0')
deterministic context-independent focus-independent

Returns a binary value created by padding $value on the left with $count occurrences of $octet.

If the value of $value is the empty sequence, the function returns an empty sequence.

Otherwise, the function returns a binary value consisting of $count instances of $octet, followed by $value.

$size must be a non-negative integer.

(replicate($octet, $count), bin:to-octets($value)) => bin:from-octets()

is raised if $size is negative.

bin:pad-left(bin:hex('FFFF'), 3) bin:hex('000000FFFF') bin:pad-left(bin:hex('0000'), 3, 255) bin:hex('FFFFFF0000') bin:pad-left(bin:hex(''), 8) bin:hex('0000000000000000')

The argument type for $octet is changed from xs:integer to xs:unsignedByte. This is made possible by the more liberal coercion rules defined in XPath 4.0. A consequence of the change is that supplying an out-of-range integer value is now a type error with the standard error code XPTY0004, rather than the custom error code bin:octet-out-of-range previously used.

deterministic context-independent focus-independent

Returns a binary value created by padding $value on the right with $count occurrences of $octet.

If the value of $value is the empty sequence, the function returns an empty sequence.

Otherwise, the function returns a binary value consisting of $value, followed by $count instances of $octet.

$size must be a non-negative integer.

(bin:to-octets($value), replicate($octet, $count)) => bin:from-octets()

is raised if $size is negative.

bin:pad-right(bin:hex('FFFF'), 3) bin:hex('FFFF000000') bin:pad-right(bin:hex('0000'), 3, 255) bin:hex('0000FFFFFF') bin:pad-right(bin:hex(''), 8) bin:hex('0000000000000000')

The argument type for $octet is changed from xs:integer to xs:unsignedByte. This is made possible by the more liberal coercion rules defined in XPath 4.0. A consequence of the change is that supplying an out-of-range integer value is now a type error with the standard error code XPTY0004, rather than the custom error code bin:octet-out-of-range previously used.

deterministic context-independent focus-independent

Returns the position of the first occurrence of $search within $value, starting at $offset.

If the value of $value is the empty sequence, the function returns an empty sequence.

Otherwise, the function returns the lowest value of P that is greater than or equal to $offset, such that bin:part($value, P, bin:length($search)) eq P. If there is no such value (that is, if $search is not found), the function returns the empty sequence.

If $search is then $offset is returned.

The value of $offset must be a non-negative integer.

The $offset is zero based.

The returned location is zero based.

($offset to (bin:length($value) - bin:length($search))) [bin:part($value, 0, bin:length($search)) eq $search][1]

is raised if $offset is negative or $offset is larger than the size of the binary data of $value.

Finding all the matches can be accomplished with simple recursive application:

]]>
bin:find((bin:hex('AABBCCDD'), 0, bin:hex('DD')) 3 bin:find((bin:hex('AABBCCDD'), 0, bin:hex('FF')) () bin:find((bin:hex('AABBCCDDBBCC'), 2, bin:hex('BBCC')) 4 bin:find((bin:hex('AABBCCDD'), 2, bin:hex('')) 2
deterministic context-independent focus-independent

Examines a binary value that encodes a string, to determine the encoding and the start offset of the content.

The value for the encoding candidate E is fn:upper-case($encoding), or an empty sequence if no encoding is supplied.

The effective encoding is determined as follows:

UTF-8 if E is UTF-8 or absent, and if the initial octets are xEF, xBB and xBF; otherwise,

UTF-16LE if E is UTF-16, UTF-16LE or absent, and if the initial octets are xFF and xFE; otherwise,

UTF-16BE if E is UTF-16, UTF-16BE or absent, and if the initial octets are xFE and xFF; otherwise,

UTF-16BE if E is UTF-16; otherwise,

the original value of $encoding if E is present; otherwise,

UTF-8, or a value that results from implementation-defined heuristics.

The effective start position is zero, unless the initial octets represent a byte order mark that has been evaluated by the above rules, in which case the effective start position is the zero-based offset (counting in octets) at which the byte order mark ends.

The function returns a record with two fields:

encoding contains the effective encoding.

offset contains the effective start position.

is raised if $encoding is invalid or not supported by the implementation.

The function is designed to be used in conjunction with bin:decode-string. Having established an encoding and a start offset, these can be used as arguments to the bin:decode-string function to decode the data.

Unlike functions such as fn:unparsed-text, this function does not have access to external data such as HTTP headers that might assist in establishing the encoding.

bin:infer-encoding(bin:hex('41 42 43')) { "encoding": "UTF-8", "offset": 0 } bin:infer-encoding(bin:hex('EFBBBF 41 42 43')) { "encoding": "UTF-8", "offset": 3 } bin:infer-encoding(bin:hex('FEFF 0041 0042 0043')) { "encoding": "UTF-16BE", "offset": 2 } bin:infer-encoding(bin:hex('0041 0042 0043'), "UTF-16BE") { "encoding": "UTF-16BE", "offset": 0 } bin:infer-encoding(bin:hex('FFFE 4100 4200 4300')) { "encoding": "UTF-16LE", "offset": 2 } bin:infer-encoding(bin:hex('FFFE 4100 4200 4300'), 'utf-16') { "encoding": "UTF-16LE", "offset": 2 } let $input := bin:hex('FFFE 4100 4200 4300') let ${$encoding, $offset} := bin:infer-encoding($input) return bin:decode-string($input, $encoding, $offset) "ABC"

New in 4.0

deterministic context-independent focus-independent

Decodes a binary value as a string.

If the value of $value is the empty sequence, the function returns an empty sequence.

If $offset or $size is non-empty, the effective value is computed by invoking bin:part($value, $offset otherwise 0, $size). Otherwise, it is $value.

The $encoding argument, if present, follows the same rules as for the encoding attribute in an XML declaration; every implementation recognizes at least the required encodings.

The effective encoding and start position is determined by invoking bin:infer-encoding with the effective value and $encoding.

The result of the function is a string representation of the effective value, starting at the effective offset, and decoded according to the effective encoding.

is raised if $offset is negative or $offset + $size is larger than the size of the binary data of $value.

is raised if $encoding is invalid for the given input.

is raised if $size is negative.

is raised if $encoding is invalid or not supported by the implementation.

is raised if there is an error or malformed input during decoding the string. Additional information about the error may be passed through suitable error reporting mechanisms – this is implementation-dependent.

bin:decode-string(bin:hex('41 42 43')) "ABC" Whitespace in this and the following examples has been added for clarity. bin:decode-string(bin:hex('EFBBBF 41 42 43')) "ABC" bin:decode-string(bin:hex('FFFE 4100 4200 4300')) "ABC" Little-endian byte order is used because of the BOM at the start of the data. bin:decode-string(bin:hex('41 42 43'), offset := 1) "BC" bin:decode-string(bin:hex('41 42 43'), offset := 1, size := 1) "B" bin:decode-string(bin:hex('41 42 43 44'), 'UTF-8', 3) "D" bin:decode-string(bin:hex('EFBBBF 41 42 43 44'), (), 3) "ABCD"

The following tests whether the binary value $data starts with four octets that decode to the string "%PDF" (which always appears at the start of a PDF file).

bin:decode-string($data, size := 4) eq '%PDF'

The revised encoding rules take byte order marks into account.

deterministic context-independent focus-independent

Encodes a string into a binary value using a given encoding.

If the value of $value is the empty sequence, the function returns an empty sequence.

The $encoding argument is the name of an encoding. The values for $encoding follow the same rules as for the encoding attribute in an XML declaration; every implementation recognizes at least the required encodings. The encoding UTF-16 is interpreted as UTF-16BE (that is, most significant byte first).

The function returns the binary value obtained by encoding the string $value using the specified $encoding name.

The function does not add a byte order mark to the data. But if $value includes a byte order mark (U+FEFF) then it is encoded in the same way as any other character.

is raised if $encoding is invalid or not supported by the implementation.

is raised if there is an error or malformed input during encoding the string. Additional information about the error may be passed through suitable error reporting mechanisms – this is implementation-dependent.

bin:encode-string('ABC') bin:hex('414243') bin:encode-string('ABC', 'UTF-16') bin:hex('004100420043') The result has no BOM, and uses big-endian encoding. bin:encode-string(char(0xfeff) || 'ABC', 'UTF-16LE') bin:hex('fffe410042004300') The result has a BOM, and uses little-endian encoding.

The handling of byte order marks has been clarified. This may differ from the interpretation adopted by existing implementations.

deterministic context-independent focus-independent

Returns the twos-complement binary representation of an integer value as a binary value of a given size.

The function produces a binary value containing the twos-complement representation of $value mod math:pow(256, $size), padded on the left to $size octets with zero bits if the value is positive, or one bits if it is negative.

Acceptable values for $order are described in . If least-significant-first ordering is requested then the order of octets in the result is reversed.

Specifying a $size of zero yields a binary value.

is raised if $size is negative.

If the integer being packed has a maximum precision of $size octets, then signed/unsigned versions are not necessary. If the data is considered unsigned, then the most significant bit of the bottom $size octets has a normal positive (2^(8 *$size - 1)) meaning. If it is considered to be a signed value, then the MSB and all the higher order, discarded bits will be '1' for a negative value and '0' for a positive or zero. If this function were to check the sizing of the supplied integer against the packing size, then any values of MSB and the discarded higher order bits other than 'all 1' or 'all 0' would constitute an error. This function does not perform such checking.

Least-significant-first byte ordering simply reverses the octets in the result.

bin:pack-integer(256, 2) bin:hex('0100') bin:pack-integer(256, 4) bin:hex('00000100') bin:pack-integer(65536, 2) bin:hex('0000') bin:pack-integer(256, 2, "LE") bin:hex('0001') bin:pack-integer(-1, 2) bin:hex('FFFF') bin:pack-integer(-2, 4) bin:hex('FFFFFFFE') bin:pack-integer(-2, 4, 'LE') bin:hex('FEFFFFFF')
deterministic context-independent focus-independent

Returns a signed integer value represented by the $size octets starting from $offset in the input binary value.

The function produces an integer represented by the binary value bin:part($value, $offset, $size). This is interpreted as a twos-complement representation of a signed integer.

Acceptable values for $order are described in . If least-significant-first ordering is requested then the order of octets in the input is reversed.

The values of $offset and $size must be non-negative integers.

$offset is zero based.

Specifying a $size of zero yields the integer 0.

is raised if $offset is negative or $offset + $size is larger than the size of the binary data of $value.

is raised if $size is negative.

is raised if $size is too large for the implementation-defined maximum integer size.

For discussion on integer range see .

bin:unpack-integer(bin:hex('0100'), 0, 2) 256 bin:unpack-integer(bin:hex('00000100'), 0, 4) 256 bin:unpack-integer(bin:hex('FFFF'), 0, 2) -1 bin:unpack-integer(bin:hex('00FFFFFFFF'), 1, 4) -1 bin:unpack-integer(bin:hex('FEFF'), 0, 2, "LE") -2
deterministic context-independent focus-independent

Returns an unsigned integer value represented by the $size octets starting from $offset in the input binary representation.

The function produces an integer represented by the binary value bin:part($value, $offset, $size). This is interpreted as a representation of an unsigned integer.

Acceptable values for $order are described in . If least-significant-first ordering is requested then the order of octets in the input is reversed.

The values of $offset and $size must be non-negative integers.

$offset is zero based.

Specifying a $size of zero yields the integer 0.

is raised if $offset is negative or $offset + $size is larger than the size of the binary data of $value.

is raised if $size is negative.

is raised if $size is too large for the implementation-defined maximum integer size.

For discussion on integer range see .

bin:unpack-unsigned-integer(bin:hex('0100'), 0, 2) 256 bin:unpack-unsigned-integer(bin:hex('00000100'), 0, 4) 256 bin:unpack-unsigned-integer(bin:hex('FFFF'), 0, 2) 65535 bin:unpack-unsigned-integer(bin:hex('00FFFFFFFF'), 1, 4) 4294967295 bin:unpack-integer(bin:hex('FEFF'), 0, 2, "LE") 65279
deterministic context-independent focus-independent

Extracts an xs:double value held in IEEE format at the given offset in a binary value.

Extract the double value stored in the 8 successive octets from the $offset octet of the binary data of $value.

Acceptable values for $order are described in .

The value of $offset must be a non-negative integer.

The $offset is zero based.

The binary representation is expected to correspond with that of the IEEE double-precision 64-bit floating point type . For more details see .

is raised if $offset is negative or $offset + 8 (octet-length of xs:double) is larger than the size of the binary data of $value.

deterministic context-independent focus-independent

Extract float value stored at the particular offset in binary data.

Extract the float value stored in the 4 successive octets from the $offset octet of the binary data of $value.

Acceptable values for $order are described in .

The value of $offset must be a non-negative integer.

The $offset is zero based.

The binary representation is expected to correspond with that of the IEEE single-precision 32-bit floating point type . For more details see .

is raised if $offset is negative or $offset + 4 (octet-length of xs:float) is larger than the size of the binary data of $value.

deterministic context-independent focus-independent

Returns the 8-octet binary representation of an xs:double value.

Acceptable values for $order are described in .

The binary representation will correspond with that of the IEEE double-precision 64-bit floating point type . For more details see .

deterministic context-independent focus-independent

Returns the 4-octet binary representation of a float value.

Acceptable values for $order are described in .

The binary representation will correspond with that of the IEEE single-precision 32-bit floating point type . For more details see .

deterministic context-independent focus-independent

Returns the bitwise OR of two binary values.

If either argument is the empty sequence, an empty sequence is returned.

Otherwise, $value1 and $value2 must have the same length.

The function converts $value1 and $value2 to sequences of bits A and B, and returns a binary value in which the Nth bit is set to 1 if either or both of the Nth bit of A and the Nth bit of B are 1, and is set to 0 otherwise.

let $octet-chars := fn($x) { bin:to-octets($x) =!> format-integer('2^xxxxxxxx') => string-join() => characters() } let $A := $octet-chars($value1) let $B := $octet-chars($value2) let $R := for-each-pair($A, $B, fn($p, $q) { if ($p eq '1' or $q eq '1') then '1' else '0' }) return bin:bin(string-join($R))

is raised if the input arguments are of differing length.

deterministic context-independent focus-independent

Returns the bitwise exclusive-OR of two binary arguments.

If either argument is the empty sequence, an empty sequence is returned.

Otherwise, $value1 and $value2 must have the same length.

The function converts $value1 and $value2 to sequences of bits A and B, and returns a binary value in which the Nth bit is set to 1 if the Nth bit of A differs from the Nth bit of B, and is set to 0 if they are the same.

let $octet-chars := fn($x) { bin:to-octets($x) =!> format-integer('2^xxxxxxxx') => string-join() => characters() } let $A := $octet-chars($value1) let $B := $octet-chars($value2) let $R := for-each-pair($A, $B, fn($p, $q) { if ($p ne $q) then '1' else '0' }) return bin:bin(string-join($R))

is raised if the input arguments are of differing length.

deterministic context-independent focus-independent

Returns the bitwise AND of two binary arguments.

If either argument is the empty sequence, an empty sequence is returned.

Otherwise, $value1 and $value2 must have the same length.

The function converts $value1 and $value2 to sequences of bits A and B, and returns a binary value in which the Nth bit is set to 1 if both the Nth bit of A and the Nth bit of B are 1, and is set to 0 otherwise.

let $octet-chars := fn($x) { bin:to-octets($x) =!> format-integer('2^xxxxxxxx') => string-join() => characters() } let $A := $octet-chars($value1) let $B := $octet-chars($value2) let $R := for-each-pair($A, $B, fn($p, $q) { if ($p eq '1' and $q eq '1') then '1' else '0' }) return bin:bin(string-join($R))

is raised if the input arguments are of differing length.

deterministic context-independent focus-independent

Returns the "bitwise not" of a binary argument.

Returns "bitwise not" applied to $value.

If the argument is the empty sequence, an empty sequence is returned.

let $octet-chars := fn($x) { bin:to-octets($x) =!> format-integer('2^xxxxxxxx') => string-join() } return ( $octet-chars($value) => translate('01', '10') => bin:bin() )
deterministic context-independent focus-independent

Shift the bits of a binary value left or right.

If the value of $value is the empty sequence, the function returns an empty sequence.

In other cases the length of the result is always the same as the length of $value.

If $by is positive then bits are shifted $by times to the left. The first $by bits are discarded, and $by zero bits are injected at the end.

If $by is negative then bits are shifted -$by times to the right. The last -$by bits are discarded, and -$by zero bits are injected at the start.

If $by is zero, the result is identical to $value.

If abs($by) is greater than the bit-length of $value then an all-zeroes result, of the same length as $value, is returned.

abs($by) can be greater than 8, implying multi-byte shifts.

let $string := ( bin:to-octets($value) =!> format-integer('2^xxxxxxxx') => string-join() ) let $len := string-length($string) let $shifted := if (abs($by) >= $len) then ( string-join(replicate('0', $len)) ) else if ($by >= 0) then ( substring($string, $by + 1) || replicate('0', $by) ) else ( replicate('0', -$by) || substring($string, 1, -$by) ) return bin:bin($shifted)

Bit shifting across byte boundaries implies “big-endian treatment”, i.e. the leftmost (high-order) bit when shifted left becomes the low-order bit of the preceding byte.

bin:shift(bin:hex("000001"), 17) bin:hex("020000")
deterministic context-independent focus-independent

Rotates the bits of a binary value left or right.

If the value of $value is the empty sequence, the function returns an empty sequence.

In other cases the length of the result is always the same as the length of $value.

If $by is positive the bits are rotated $by places to the left. The high-order bits shifted out at the front re-enter at the end.

If $by is negative then the bits are rotated -$by places to the right.

If $by is zero, the result is identical to $value.

The rotation is cyclic modulo the bit-length of $value: rotating by the bit-length, or a multiple of it, returns $value unchanged.

let $string := ( bin:to-octets($value) =!> format-integer('2^xxxxxxxx') => string-join() ) let $len := string-length($string) let $r := (($by mod $len) + $len) mod $len return bin:bin(substring($string, $r + 1) || substring($string, 1, $r))

Like bin:shift, rotation across byte boundaries follows big-endian treatment. Unlike bin:shift, no bits are discarded and no zero bits are injected.

bin:rotate(bin:hex('81'), 1) bin:hex('03') bin:rotate(bin:hex('81'), -1) bin:hex('C0')

New in 4.0

deterministic context-independent focus-independent

Determines whether a particular bit of a binary value is set.

If the value of $value is the empty sequence, the function returns an empty sequence.

In other cases returns true if the bit at position $index in $value is set, or false otherwise.

Bits are numbered from the start of the binary value: index 0 is the most significant bit of the first octet, index 7 its least significant bit, index 8 the most significant bit of the second octet, and so on.

let $bits := ( bin:to-octets($value) =!> format-integer('2^xxxxxxxx') => string-join() ) return substring($bits, $index + 1, 1) = '1'

is raised if $index is negative or not less than the number of bits in $value.

bin:is-bit-set(bin:hex('80'), 0) true bin:is-bit-set(bin:hex('80'), 7) false

New in 4.0

deterministic context-independent focus-independent

Returns a binary value with selected bits set or cleared.

If the value of $value is the empty sequence, the function returns an empty sequence.

In other cases returns a binary value identical to $value with the bit at each position in $indices set to 1 if $set is true, or to 0 otherwise.

Bits are numbered as for bin:is-bit-set: index 0 is the most significant bit of the first octet. The order of $indices is insignificant, and repeated indices have no additional effect.

The length of the result is always the same as the length of $value. If $indices is empty, the result is identical to $value.

fold-left( $indices, $value, fn($result, $index) { let $bits := ( bin:to-octets($result) =!> format-integer('2^xxxxxxxx') => string-join() ) return bin:bin( substring($bits, 1, $index) || (if ($set) then '1' else '0') || substring($bits, $index + 2) ) } )

is raised if any value in $indices is negative or not less than the number of bits in $value.

bin:set-bits(bin:hex('00'), (0, 7), true()) bin:hex('81') bin:set-bits(bin:hex('FF'), (0, 7), false()) bin:hex('7E')

New in 4.0

deterministic context-independent focus-independent

Returns the number of one-bits in a binary value.

If the value of $value is the empty sequence, the function returns an empty sequence.

In other cases the number of bits is returned that are set to 1 in $value.

bin:to-octets($value) =!> format-integer('2^xxxxxxxx') => string-join() => replace('0') => string-length()

The result is also known as the population count.

The Hamming distance between two binary values of equal length can be computed as bin:count-bits-set(bin:xor($value1, $value2)).

bin:count-bits-set(bin:hex('')) 0 bin:count-bits-set(bin:hex('FF_FF_FF_FF')) 32

New in 4.0