Skip to content

tompecina/bitwriter

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

========= BITWRITER

(C) 2015 Tomáš Pecina tomas@pecina.cz, GNU General Public License Version 3

  1. ABOUT BITWRITER

Bitwriter is a Java application capable of transforming an XML input file into binary output. Compared to simple binary data-processing utilities such as xxd, Bitwriter is much more versatile, as it understands rich input vocabulary, including variables, looping constructs, parity/checksum/CRC/message digest calculators, and enhanced JavaScript scripting.

The main features of Bitwriter include:

  • input in XML, which can be read from files and/or command-line parameter strings

  • six-stage data stream processing stack supporting input/output bit reflection and unlimited-size (BigInteger) integer values

  • 70+ built-in CRC models, plus custom models

  • all standard formats of message digests currently supported by Java (MD-5, SHA-1, SHA-256, etc.)

  • all data in XML, including attributes, can be generated by Nashhorn (JavaScript) scripts

  1. HISTORY

I created Bitwriter in June 2015 as a simple application whose main purpose was to replace various small scripts I used for generating mostly small binary files I needed for development, testing and experimenting purposes, for tasks in various fields of my interest, such as cryptography, development of embedded applications, telecommunications, retro 8-bit computer emulation, etc.

Traditional scripts are a good thing when one needs a couple of simple binaries, but they are difficult to maintain and reuse, not to mention document. My original idea was to create a simple XML transformation utility processing a vocabulary consisting of no more than five or six elements that would make it possible to write maintainable, self-documenting binary-file generators. In the end, Bitwriter's vocabulary consists of 22 elements, most of them with rich configuration options.

  1. BASICS

Writing a binary file in Bitwriter is simple and straightforward, because the semantics of most elements is self-explanatory. A sample Bitwriter input file may look like this:

Hello world! 0d 0a 00

This input generates a file containing the ASCII string "Hello world!" followed by an MS-DOS/Windows end-of-line sequence and a zero (null) byte.

However, Bitwriter is not a text writing application, and it is definitely not its forte. Let's consider something more appropriate to its binary nature: a file consisting of a preamble of sixteen 0x33's, followed by a series of 512 integers of 5000, stored as 32-bit values, little-endian, followed by a CRC-16/CCITT checksum computed over the whole sequence of the integers and stored, for a change, as big-endian. This can be accomplished by the following Bitwriter script:

0x33 5000

Finally, to demonstrate the power of Bitwriter's scripting, this is an example of a 1KiB block of pseudo-random data followed by an LRC (Longitudinal Redundancy Check) conforming to ISO 1155. There are too many different checksum types to implement, therefore, the decision was to "hard-code" only the most basic and rudimentary ones to Bitwriter and resort to scripting for the rest. This is where Bitwriter really shines; the solution can be as simple as this:

More examples can be found in the examples/ directory of the package.

  1. COMMAND-LINE ARGUMENTS

Bitwriter is a platform-independent Java application, typically run from a JAR file. It has no configuration file, its operation is controlled solely by the command-line arguments.

Usage: bitwriter [options] [--] [input-file]...

In its most basic mode, the application takes its input XML file(s) and outputs the binary file generated according to the XML description either to STDOUT, or to an output file, provided the pathname is given by the -o option. Input can also be specified directly by one or more literal strings (the -s option). These can be either complete XML files starting with the "<?xml ..." preamble, or the content normally put between and . If no other source of input is provided, the application tries to read its input from STDIN.

Detailed description of all available command line options follows:

-?,--help

The application outputs the usage information and exits.

-V,--version

The version number is displayed.

-c,--crc-file

The pathname of the file containing XML presets. If this option is omitted, CRC models are read from a default internal file, containing ca 80 most common models.

-l,--list-crc-models

The application prints out the parameters of all preset CRC models and exits. The listing contains the following fields for each model:

ID: the unique identification string of the model

Alias/es: a list of names; a model can be invoked using either its ID or any of the aliases

Width: width of the generator polynomial in bits

Poly: the generator polynomial in normal notation, printed as a hexadecimal string

RefIn: reflect-in parameter, "F" stands for "false, "T" for true; if set, bits are processed by the CRC shift register in reverse order, i.e., LSB (bit 0) is read first and MSB (bit 7) last

XorIn: the xor-in value, which is put into the CRC register before reading the first bit/byte

RefOut: reflect-out; if set, the register is read LSB-first; in most cases, RefIn==RefOut, "cross-endian" models are rather exotic and rare

XorOut: the xor-out mask which is used for exclusive-or'ing the register before outputting its value

-o,--output-file

The pathname of the output file. If no output file is provided on the command line, STDOUT is used. Error messages are always output to STDERR.

-s,--string

One or more strings that are used as input instead of (or in addition to) the input file(s). If the string starts with "<?xml ", its contents is used as the input without modification, otherwise, it is put within the element, for instance, -s '55aa0033ccff'. If both input string(s) and file(s) are specified, the strings are processed first, in the order of appearance, then the files, one after another as they appear on the command line. The content of each string and file is processed as a separate unit, i.e., the concatenation takes place on the binary output level. If the XML prolog is specified, the encoding (charset) is set to the default used by the operating system.

-x,--hex-mode

In hexadecimal mode, human-readable hexadecimal output is produced instead of binary data. This is useful for debugging.

  1. INPUT DATA FORMAT

Bitwriter reads and processes only well-formed and valid XML data in any encoding recognized by the JRE (Java Runtime Environment). The format of the XML data is straightforward and easy to understand, with no irregularities or idiosyncrasies. It reminds more of a scripting or programming language than a data XML file.

The XML Schema describing the vocabulary and semantics of the XML file can be downloaded from my personal website (http://www.pecina.cz/xsd/bin-1.0.xsd).

All attributes, with the single exception of "version" in the element, can be provided either by a literal string, such as "stream-out", "false" or "0xff", or a script invocation, enclosed in double braces, e.g., "{{ i++ }}".

Bitwriter understands the following literal data:

Numbers: An integer can be expressed in hexadecimal, decimal, octal or binary representation of any length. Hexadecimal numbers must be preceded by 0x or 0X, binary numbers by 0b or 0B, octals must have a leading 0. All numbers are internally represented as Java's BigInteger objects so there is no limit as to their size.

Boolean values: The format of XML Schema type xs:boolean is accepted, i.e., "true"/"false" or "1"/"0".

String constants: These must be given verbatim, case-sensitive, without quotation marks or internal whitespace characters; quotes are used only when the string is the output of a script, e.g., {{ 'little' }}; without the quotes, the script engine would output the value of the variable named "little" rather than the string "little".

Numeric sequences: The format of numeric sequences depends on the element/context and will be described separately for each element in which they can appear.

These are the elements that can be put in the XML input file:

File is the root element of every input file. It must always be present and is valid only on the top level.

Attributes:

"version" -- Required. Must be equal to "1.0", otherwise, the XML will not be recognized as valid input for this version of Bitwriter.

Content:

Any elements allowed on the outer level, i.e., , , <script> and any variable-related elements except .

is the key element of the vocabulary, describing the transformations applied to the input data (i.e., the data model). It can only appear on the outer level, either directly as a child of or within a (possibly nested) .

Content:

Mixed content, a sequence of literal values, scripts and elements. Literals and scripts (enclosed in "{{" and "}}"), are interpreted as numeric data and are written immediately to the input streams. All elements except , and are allowed inside a .

Attributes:

"repeat" -- Optional, non-negative integer, default "1". Number of times the stream is repeated. The repetition occurs on the semantic level, i.e., the interpretation is exactly as if the element with identical contents was repeated rather than the binary output it generates.

"width-in" -- Optional, default "8". The width of the input stream in bits. If no "width-aggregate-in" is specified, it also sets the width of the aggregate input stream.

"width-aggregate-in" -- Optional, default "8". The bit width of the aggregate input stream. If this attribute is not specified, the value is copied from "width-in".

"width-aggregate-out" -- Optional, default "8". The bit width of the aggregate output stream.

"width-out" -- Optional, defaul "8". The bit width of the output stream. It depends on the computer architecture, and can only be set to "8". Any other value causes an error.

"endianness-in" -- Optional, default "big". The input endianness mode, determining the mode for transferring data between the input and aggregate input stream. Possible values are "big" and "little". If "big", the data is copied without any transformation, if "little", the order of elements (not necessarily bytes) is reversed.

"endianness-out" -- Optional, values like for "endianness-in", default "little". The output endianness mode, determining the manner in which the output stream is formed from the aggreagate output.

"reflect-in" -- Optional, Boolean, default "false". It determines the order in which bits enter the bit stream. If "true", the bit order is reversed, i.e., LSB comes in the first, MSB the last.

"reflect-out" -- Optional, Boolean, default "false". It determines the order in which bits leave the bit stream. If "true", bit order is reversed, i.e., LSB comes out the first, MSB the last.

"discard" -- Optional, Boolean, default "false". If true, the data from the stream is not written to the output, but everything else occurs as if it did, e.g., variables are updated and processed, scripts are evaluated, etc. In general, this is not a good method for temporarily "turning off" a stream. If you need this effect, use repeat="0" or comment the stream element out.

The element is the looping construct that can be used only on the outer level. It is somewhat similar to , but cannot appear inside a stream. Unlike streams, loops can be nested.

Content:

All elements allowed on the outer level, i.e., outside a stream, namely , , <script> and any variable-related elements except .

Attributes:

"repeat" -- Optional, non-negative integer, default "1". Number of times the contents of the loop element is repeated. Like all the other cases where "repeat" is allowed, the repetition is semantic, taking place on the input code level rather than on the output data.

Hexadecimal data. Unlike the other radix-based elements, whitespace is ignored and all non-whitespece characters are intepreted as pairs of hexadecimal digits, representing 8-bit values. If wider numbers are to be interpreted, input aggregation can be used.

Content:

Literal data, including scripts, and <script>. Script are interpreted just like in a , i.e., no radix conversion is performed.

Attributes:

"repeat" -- Optional, non-negative integer, default "1". Number of times the sequence is repeated.

Decimal data. As this is the default mode for sequences, is rather meaningless and is only provided for the symmetry's sake.

Content:

Decimal numbers, including scripts, and <script>.

Attributes:

"repeat" -- Optional, non-negative integer, default "1". Number of times the sequence is repeated.

Octal data. The content tokens are interpreted as octal data.

Content:

Octal numbers, including scripts, and <script>.

Attributes:

"repeat" -- Optional, non-negative integer, default "1". Number of times the sequence is repeated.

Binary data. The content stream is interpreted as binary data. Unlike , the sequence is tokenized.

Content:

Binary numbers, including scripts, and <script>.

Attributes:

"repeat" -- Optional, non-negative integer, default "1". Number of times the sequence is repeated.

Bit stream. The content sequence is taken character by character and written to the input stream either as 0 or 1. It is important to understand the difference between and . While the latter can be used for representing any numeric value, can only express "zero" or "one" and input or output aggregation/de-aggregation mechanism must be employed for a wider base output. Example: 01010101 means one value 0x55, 01010101 is actually eight distinct values: 0, 1, 0, 1, 0, 1, 0, and 1.

Content:

Bit values, including scripts, and <script>.

Attributes:

"repeat" -- Optional, non-negative integer, default "1". Number of times the sequence is repeated.

Floating point data. The content tokens are interpreted as floating point data, conforming to IEEE 754 "binary32" format. All formats suppported by Java are permitted. Like all sequence elements, the result is put into one numeric value of the input stream, and it is up to the user to provide for appropriate storage.

Content:

Floating-point numbers, including scripts, and <script>.

Attributes:

"repeat" -- Optional, non-negative integer, default "1". Number of times the sequence is repeated.

Floating point data. The content tokens are interpreted as floating point data, conforming to IEEE 754 "binary64" format. All formats suppported by Java are permitted. Like with all sequence elements, the result is put into one numeric value of the input stream, and it is up to the user to provide for appropriate storage.

Content:

Floating-point numbers, including scripts, and <script>.

Attributes:

"repeat" -- Optional, non-negative integer, default "1". Number of times the sequence is repeated.

Character stream. The data is extracted from the text in the content of the element, according to the rules specified by the "wrap" and "charset" attributes. Special characters can be expressed using XML entities, e.g., "�".

Content:

Character data, and <script>.

Attributes:

"repeat" -- Optional, non-negative integer, default "1". Number of times the contents is repeated.

"wrap" -- Optional, Boolean, default "true". If "false", all characters are copied, including any leading and trailing whitespace characters, if "true", they are removed from the string before further processing.

"charset" -- Optional, default is the default encoding (charset) of the operating system. The charset (character set) used for converting the text string to bytes. All charsets recognized by Java are accepted, plus "raw", which means that the code-point number of the character is used rather then its -- possibly multi-byte -- representation.

Looping construct similar to , but permitted only inside a stream. Like , it can be nested.

Content:

Any content legal in a , including .

Attributes:

"repeat" -- Optional, non-negative integer, default "1". Number of times the contents is repeated.

<script> The script is evaluated, but the return values is discarded, so only the side-effects of the execution are important. The <script> element can be used anywhere, inside or outside a stream. Content: The script string, not enclosed in double braces. Attributes: "repeat" -- Optional, non-negative integer, default "1". Number of times the script is executed. An empty element causing any data currently in the stream buffers to be written downstream. It is valid only inside a stream. Content: None. Attributes: None. Sets the value of the variable. If the variable does not exist, it is created and reset (i.e., set to "0"). Content: None. Attributes: "name" -- Required. Name of the variable, an identifier consisting of uppercase or lowercase letters, digits and special characters '_' and '$'. It may not start with a digit. Variable names are case sensitive. "value" -- Optional, integer. If specified, the variable is set to the value. If specified as a script, it is evaluated immediately. The script is executed as the first action during the write, preceding any other activity, in particular before the value is processed and written downstream. This means that in the course of a regular write cycle, the triggers are activated in the downstream direction, i.e., "on-input-stream" first and "on-output-stream" last. "on-stream-in" -- Optional, integer. A value to which the variable is set on any write to input stream. Typically a script, evaluation is deferred until the actual write and triggering of the event. In addition to normal XML variables, the binding includes the variable "val", set to the BigInteger data just written. If the attibute is omitted, the previous value is preserved; to delete the string, an empty string, i.e., "", must be spefically indicated as the attribute value. "on-aggregate-stream-in" -- Optional, integer. The same as "on-stream-in", but triggered by a write to the aggregate input stream. "on-bitstream" -- Optional, integer. The same as "on-stream-in", but triggered by a write to the bit stream. "on-aggregate-stream-out" -- Optional, integer. The same as "on-stream-in", but triggered by a write to the aggregate output stream. "on-stream-out" -- Optional, integer. The same as "on-stream-in", but triggered by a write to the output stream. "on-output-stream" -- Optional, integer. The same as "on-stream-in", but triggered by a write to the controlled output stream. The variable is reset to "0", all trigger scripts are removed and if it has been set up as a calculator, it is switched back to normal mode. If the variable does not exist, it is created. Content: None. Attributes: "name" -- Required, the identifier of the variable. The variable is released, i.e., all its scripts are reset and it is set to normal mode. The value in preserved. The variable must exist, or an error is reported. This is practical for situations when a calculator, e.g., a CRC, is not written to the stream immediately after the data it protects. After the data block the variable is released, so it stops updating, and any postamble data can be written. Content: None. Attributes: "name" -- Required, the identifier of the variable. The content of the variable or value is written to the selected stream. Unlike normal data sequences, which are always written to the input stream, can be used for writing to any of the six streams. By default, also resets the variable. It is important to keep in mind that only one integer is written, though it can be split into multiple bytes using the stream's aggregation/de-aggregation mechanism. The element can only appear inside a stream. Content: None. Attributes: "name" -- Optional, the identifier of the variable. If specified, the variable must exist. "value" -- Optional, integer value to be written instead of the variable. Either "name" or "value" must be specified. "type" -- Optional, default "stream-in". Destination stream for the data. Possible values are: "stream-in", "aggregate-stream-in", "bitstream", "aggregate-stream-out", "stream-out", "output-stream". "reset" -- Optional, Boolean, default "true". If "true", the variable is reset before writing the data to the stream. No effect if "value" instead of "name" is given. This is mainly for debugging: the variable or value is written, in decimal and hexadecimal representation, to STDERR. Content: None. Attributes: "name" -- Optional, the identifier of the variable. If specified, the variable must exist. "value" -- Optional, integer value to be written instead of the variable. Either "name" or "value" must be specified. The variable is set up as a calculator computing parity of the least significant bit of each value written to the stream it is connected to. Like the other calculators, the variable is created and reset if it does not exist. Content: None. Attributes: "name" -- Required, the identifier of the variable. If the variable does not exist, it is created. "type" -- Optional, default "bitstream". The stream to which the calculator is connected. The options are "stream-in", "aggregate-stream-in", "bitstream", "aggregate-stream-out", "stream-out", "output-stream"; however, is a one-bit calculator, so it only makes sense to connect it to the bit stream. "model" -- Optional, "even" or "odd", default "odd". The type of parity to be calculated. The variable is set up as a checksum over all the values written to the stream it is connected to. The variable is created and reset if it does not exist. Content: None. Attributes: "name" -- Required, the identifier of the variable. If the variable does not exist, it is created. "type" -- Optional, default "stream-out". The stream to which the calculator is connected. The options are "stream-in", "aggregate-stream-in", "bitstream", "aggregate-stream-out", "stream-out", "output-stream". "width" -- Optional, positive integer, default "8". The bit width of the checksum. "xor-in" -- Optional, integer, default "0". The initial value of the register. "xor-out" -- Optional, integer, default "0". The register is exclusive-or'ed with this value before it is put to the variable. The variable is set up as a CRC (Cyclic Redundancy Check) over all the values written to the selected stream. The variable is created and reset if it does not exist. Content: None. Attributes: "name" -- Required, the identifier of the variable. If the variable does not exist, it is created. "type" -- Optional, default "stream-out". The stream to which the calculator is connected. The options are "stream-in", "aggregate-stream-in", "bitstream", "aggregate-stream-out", "stream-out", "output-stream". "model" -- Optional. The ID or name (alias) of the model as defined in the presets file (see above). The string is case-insensitive. If "model" is supplied, its parameters can still be overridden by providing individual attributes. "notation" -- Optional, default "normal". The notation in which the generator polynomial is expressed. It is always expressed as a value of the polynomial for x = 2, the difference is the pre-substitution transformations of the polynomial. The options are: "normal" -- the polynomial's highest-degree coefficient is omitted (this is the most common notation); "full" -- all terms are included without any change; "reversed" -- the highest-degree term is omitted and the remaining coefficients are reversed; "koopman" -- Koopman's notation, in which the lowest-degree coefficient is omitted and the polynomial is divided by x, i.e., its representation is shifted one bit to the right. Example: the polynomial x ^ 8 + x ^ 2 + x + 1 will be expressed as follows: normal 0x7, full 0x107, reversed 0xe0, Koopman's 0x83. "width" -- Required or optional (see below), positive integer. The bit width of the polynomial. If the notation is "full" or "koopman", it can be derived from the representaiton of the polynomial, for "normal" and "reversed", it is a required attribute. "polynomial" -- Optional, integer > 1. The numeric representation of the generator polynomial in the given notation. "reflect-in" -- Optional, Boolean, default "true". A parameter of the CRC model determining the order in which bits are processed by the shift register. If "true", the MSB bit is processed first, otherwise the LSB bit. "xor-in" -- Optional, integer, default "-1". The initial value of the register. "reflect-out" -- Optional, Boolean, default "false". It determines the order in which the bits of the register are output. If "true", the bit order is reversed, i.e., the LSB of the register is presented as the MSB. "xor-out" -- Optional, integer, default "0". The register is exclusive-or'ed with this value before it is assigned to the variable. The variable is set up as a message digest calculator over all the values written to the selected stream. The variable is created and reset if it does not exist. Content: None. Attributes: "name" -- Required, the identifier of the variable. If the variable does not exist, it is created. "type" -- Optional, default "stream-out". The stream to which the calculator is connected. The options are "stream-in", "aggregate-stream-in", "bitstream", "aggregate-stream-out", "stream-out", "output-stream". "model" -- Required. The string identifying the digest algorithm. The selection depends on the JRE in which the application is run, but all of the common digest types, such as "MD5", "SHA-1" or "SHA-256", are supported. Please refer to your current JRE documentation for a complete and current list. It generates a sequence of non-cryptographic strength pseudo-random values and writes it to the input stream. The numbers are generated by JRE's Pseudo-Random Number Generator (PRNG). None. Attributes: "width" -- Optional, integer, default "8". The bit width of the generated pseudo-random data. Due to the limitations of JRE's PRNG, which uses a 48-bit shift register, the width should not be more than "32". If you need wider data values, use Bitwriter's input or output aggregation features. "length" -- Optional, non-negative integer, default "1". The length of the generated sequence. "seed" -- Optional, integer. The seed (of Java's long type) for the PRNG. If none is provided, the JRE will gather entropy from the operating system and will (most likely) generate a different sequance each time the script is executed. Note: Although Bitwriter is not a cryptography application covering tasks dealt with by specialized cryptographic software such as OpenSSL or PGP, its ability to work natively with arbitrary size integers makes it an ideal tool for preparing cryptographic data files during development, testing and experimentation. However, don't use Bitwriter for anything that requires cryptographic strength output. This is why its functionality in this area has been deliberately clipped and it does not ship with any cryptographic library. Use Bitwriter to the full during the development phase of your project, but if you need "live" crypto data files, please don't rely on Bitwriter and write properly secured scripts. Sequence of raw data is read from an external file and written to the input stream. None. Attributes: "location" -- Required. THe pathname of the included file. "offset" -- Optional, non-negative integer, default "0". Offset of the data to be included, counted from the beginning of the file. "length" -- Optional, non-negative integer. The length (number of bytes) of the included sequence. If not specified, the whole file, or its remaining part, is included. "repeat" -- Optional, non-negative integer, default "1". Number of times the file segment is included. Please note that the inclusion is repeated by reopening the input file, so that if the contents of the file change between repetitions, different data will be included. This can be useful, e.g., for including data from a user-spplied PRNG or from an Internet socket. 6. DATA MODEL The data model -- the "data processing engine" -- used by Bitwriter is a compromise between the original idea of a fully configurable set of streams, or "channels", forming the output octet stream from the input arbitrary-width data, and the realization that practically any thinkable task can be reduced into three stages: input aggregation, bit processing, and output de-aggregation. The only thing this setup cannot handle directly are arcane and rarely used data models such as mid-endian data stream, but these can still be processed using the scripting features of the application. All data is represented as sequences of non-negative integers of unlimited bit length. Negative values are only meaningful for masking, though Bitwriter will process them correctly, clipping (masking) them as needed to fit the stream width. It is important to keep in mind that all the data streams are processed on the fly, the data is buffered only when necessary for the next stage. This is why Bitwriter keeps no record of the sequences written to the streams; if you need such records, or logs, you may employ Bitwriter's scripting features. Bitwriter operates using six data streams through which the input data is funnelled: 6.1. Input stream This is the stream where input seqences are written, value by value. Its width, expressed as a number of bits, is specified by the "width-in" parameter to . 6.2. Aggregate input stream This stream receives values from the input stream and groups them into aggregate values according to the required input endianness of the stream. The width of this stream, given by the attribute "width-aggregate-in", must be a multiple of "width-in". If this stream is wider than the input stream, the data is buffered by the input stream before it is written downstream. 6.3. Bit stream This stream has a bit width of 1 and receives data from the aggregate input stream. The data is written either MSB-first (when reflect-in="false"), or LSB-first (reflect-in="true"). 6.4. Aggregate output stream The aggregate output stream is written to by the bit stream, using the parameters "reflect-out" and "width-aggregate-out". It is thus possible to reverse the bit order of the data (or "reflect" it). As the aggregate output stream is always wider than the bit stream, the data is buffered before being written to it. 6.5. Output stream This stream has a fixed width depending on the computer architecture, which is normally "8". Its role in the engine is to prepares data for being written to the output file. The stream's main function is to de-aggregate the output data, i.e., to split it into bytes according to the required output endianness. 6.6. Controlled output stream Basically a copy of the output stream where special output processing takes place. This involves converting the data to hexadecimal representation if the command-line argument "-x" is specified, or discarding it, if required so by the "discard" attribute to the element. The flow of data through the bit processing engine is most easily understood by studying the examples as provided in this manual and in the examples/ folder of the package. 7. FORMAT OF CRC PRESET MODELS FILE The user can supply his/her own list of CRC models by way of an XML file. It is validated against the built-in XML Schema, which can be downloaded from http://www.pecina.cz/xsd/crc-1.0.xsd. The format of the XML file is relatively simple. Its root element is , with one required attribute "version", which must be equal to "1.0" for the Bitwriter to recognize it as a valid CRC models file. An example CRC file, containing only one model: CRC-32/POSIX CKSUM CRC-32 as defined by Posix 32 4c11db7 false 0 false ffffffff 765e7680 The element has one required attribute, "id". It is the unique identifier of the model. This element is a container for a (fixed-order) sequence of elements describing the model's parameters: - One or more elements, the names (or aliases) by which the model can be referred to in the input XML file. - An optional element, providing a textual description of the model. - Optional of the generator polynomial in bits, expressed as a positive decimal integer. Depending on the notation, the width may be omitted (see the explanation under the element). - The required element, containing a hexadecimal representation of the generator polynomial used by the model. It has two required parameters: "format" must always be equal to "hex", and "notation", which may be "normal", "full", "reversed" or "koopman". For a description of the different notations, see the element of Bitwriter's input XML file. - Required Boolean , the RefIn parameter of the model. Both "true"/"false" and "0"/"1" are accepted. - Required , the model's xorIn; like , it must have "format" attribute equal to "hex". - Required Boolean , the RefOut parameter of the model. - Required , the model's xorOut value; in hexadecimal notation and with the required "format" set to "hex". - The last element is the optional ; if present, it must have the "format" attribute set to "hex" and its value must be the CRC value of the ASCII string "123456789" (or {0x31, 0x32,... 0x39}). 8. BITWRITER SCRIPTING Bitwriter takes advantage of Java's Nashhorn -- a dialect of the ECMA Script, aka JavaScript -- as its scripting platform. The script context (the bindings) is shared between all the script instances within the input file or string, so that variables set in one script snippet can be referenced from all the subsequent snippets in the same XML file/string. However, there is no way how to transmit information between different input files or strings: this also applies to variables, which are reset, so that all information is forgotten (the context is deleted) at the end of the input file/string processing. There are no limitations set on the use of Nashhorn, and no limitations apply to which Java resources can be accessed by a running script. When a script is launched, its bindings have the following preset values: - All Bitwriter variables, including calculators, are set, using the same identifiers as in XML, e.g., if the XML file initialized the variable "total", it will be directly accessible from within the script as the JavaScript variable "total". The value of the variable is a BitInteger object, and it is initialized as such, but the scripting language will convert the value to a number whenever needed. This automatism is a very useful feature: it means that in most cases, the user does not have to bother about the internal representation of the variables and he/she can use them directly in arithmetic operations and function calls. One only needs to access the variables as BigInteger's when they are wider than what ECMA script's universal numeric types can handle (which is something like 53 bits). - If the script execution has been triggered by a write to a stream, the Nashhorn variable "val" is set to the value being written, as a BigInteger object. - The variable "streamNumber" is set to the number of stream, zero-based, currently being written to (like the following two variables, it is plain integer value, not a BigInteger). - The variable "streamLength" is set to the number of bytes already written to the current stream. If the current stream is being discarded, this value is still incremented, which can be used, for instance, for automatic counting of bytes written to a "buffer" variable. - Similarly, "totalLength" is the total number of bytes written to the output file. Bytes written to discarded streams are not counted in. - "BigInteger" is set to the BigInteger type so it can be used directly. - "variables" is set to Bitwriter's variables object. This is practical for more sophisticated manipulations with the variables, such as accessing the calculators and their properties. - The variable "connector" is set to a special object that provides several convenience methods as a "shortcut" to the Java methods. These are: - getProcessor() -- accessor of the InputTreeProcessor object - writeInStream(value) -- write the value to the input stream - write(value) -- the same - writeInAggregateStream(value) -- write the value to the aggregate input stream - writeBitStream(value) -- write the value to the bit stream - writeOutAggregateStream(value) -- write the value to the aggregate output stream - writeOutStream(value) -- write the value to the output stream - writeControlledOutputStream(value) -- write the value to the controlled output stream - flush() -- flush the streams When the script execution finishes, the variables are updated accroding to changes made to their JavaScript equivalents. However, this only applies to non-calculator (normal-mode) variables, calculators and their registers are never updated automatically. If the user wishes to update a calculator value from a script, he/she must do it explicitly, using the "variables" accessor object.