<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Pages on BXM.net</title>
    <link>https://bxm.net/pages/</link>
    <description>Recent content in Pages on BXM.net</description>
    <generator>Hugo</generator>
    <language>en-us</language>
    <atom:link href="https://bxm.net/pages/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>About</title>
      <link>https://bxm.net/about/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://bxm.net/about/</guid>
      <description>&lt;p&gt;BXM is two small tools that share one idea: same input, same bytes, same result. They live in one repository and on one site because they solve the same kind of problem from two ends.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;BXM Canon&lt;/strong&gt; is a binary encoding with exactly one valid form for every value. When two programs encode the same data, they get the same bytes, so a hash or a signature taken on one machine holds on every other. &lt;a href=&#34;https://bxm.net/canon/&#34;&gt;More about Canon&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>BXM Canon</title>
      <link>https://bxm.net/canon/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://bxm.net/canon/</guid>
      <description>&lt;p&gt;BXM Canon is a binary encoding with exactly one valid encoding for every value. Same data in, same bytes out, on any machine. The decoder refuses everything else, so &amp;ldquo;are these two the same?&amp;rdquo; becomes &amp;ldquo;are these bytes equal?&amp;rdquo;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-problem-it-solves&#34;&gt;The Problem It Solves&lt;/h2&gt;&#xA;&lt;p&gt;Sign a JSON object on one machine and check the signature on another, and it can fail even though nothing changed. One side wrote the keys in another order. Or &lt;code&gt;1.0&lt;/code&gt; came out as &lt;code&gt;1&lt;/code&gt;. Or a string used an escape the other side didn&amp;rsquo;t. Same data, different bytes, broken hash.&lt;/p&gt;</description>
    </item>
    <item>
      <title>BXM Memo</title>
      <link>https://bxm.net/memo/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://bxm.net/memo/</guid>
      <description>&lt;p&gt;BXM Memo skips a command when its inputs haven&amp;rsquo;t changed. Put &lt;code&gt;bxm-memo run&lt;/code&gt; in front of a slow step, say what it reads and writes, and the next time the inputs match it restores the outputs instead of running the step. When the inputs don&amp;rsquo;t match, it says which one changed.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;bxm-memo run -i &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;proto/**/*.proto&amp;#39;&lt;/span&gt; -i gen.sh -o gen/ -- ./gen.sh&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;the-problem-it-solves&#34;&gt;The Problem It Solves&lt;/h2&gt;&#xA;&lt;p&gt;Build and CI pipelines redo work whose inputs didn&amp;rsquo;t change: code generation, asset processing, test fixtures, site builds, data preparation. Each step is a few seconds or minutes, and it adds up on every push and every laptop.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Contact</title>
      <link>https://bxm.net/contact/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://bxm.net/contact/</guid>
      <description>&lt;p&gt;Bug reports, feature requests and pull requests are welcome on &lt;a href=&#34;https://github.com/softdevstudio/bxm/issues&#34;&gt;GitHub&lt;/a&gt;. That&amp;rsquo;s the fastest way to get something fixed, and other people can see the answer.&lt;/p&gt;&#xA;&lt;p&gt;For anything else, write to &lt;strong&gt;&lt;a href=&#34;mailto:info@bxm.net&#34;&gt;info@bxm.net&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;&#xA;&lt;p&gt;The project would especially like to hear from:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;People writing another Canon implementation&lt;/strong&gt;, in any language, who find a corner of the &lt;a href=&#34;https://bxm.net/reference/&#34;&gt;spec&lt;/a&gt; that could be read two ways.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Teams trying Memo in CI&lt;/strong&gt;, about what they wrapped, how much time it saved and what got in the way.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Anyone who signs or hashes structured data&lt;/strong&gt; and has been bitten by two systems writing the same thing differently.&lt;/li&gt;&#xA;&lt;/ul&gt;</description>
    </item>
    <item>
      <title>Download BXM</title>
      <link>https://bxm.net/download/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://bxm.net/download/</guid>
      <description>&lt;p&gt;Each archive holds both tools, &lt;code&gt;bxm-canon&lt;/code&gt; and &lt;code&gt;bxm-memo&lt;/code&gt;, plus the Canon library and C header, the format spec with its test vectors, and the license files. The links always point to the latest release.&lt;/p&gt;&#xA;&lt;div style=&#34;overflow-x:auto&#34;&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;System&lt;/th&gt;&#xA;          &lt;th&gt;Download&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Linux, x86-64&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://github.com/softdevstudio/bxm/releases/latest/download/bxm-linux-amd64.tar.gz&#34;&gt;bxm-linux-amd64.tar.gz&lt;/a&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Linux, ARM64&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://github.com/softdevstudio/bxm/releases/latest/download/bxm-linux-arm64.tar.gz&#34;&gt;bxm-linux-arm64.tar.gz&lt;/a&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;macOS, Apple silicon&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://github.com/softdevstudio/bxm/releases/latest/download/bxm-darwin-arm64.tar.gz&#34;&gt;bxm-darwin-arm64.tar.gz&lt;/a&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;macOS, Intel&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://github.com/softdevstudio/bxm/releases/latest/download/bxm-darwin-amd64.tar.gz&#34;&gt;bxm-darwin-amd64.tar.gz&lt;/a&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Windows, x86-64&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://github.com/softdevstudio/bxm/releases/latest/download/bxm-windows-amd64.zip&#34;&gt;bxm-windows-amd64.zip&lt;/a&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;p&gt;To check a download, compare it with &lt;a href=&#34;https://github.com/softdevstudio/bxm/releases/latest/download/SHA256SUMS&#34;&gt;SHA256SUMS&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;canon-for-javascript&#34;&gt;Canon for JavaScript&lt;/h2&gt;&#xA;&lt;p&gt;The &lt;code&gt;bxm-canon&lt;/code&gt; package for Node 18+ and browsers is attached to every release:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Quick Start</title>
      <link>https://bxm.net/quick-start/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://bxm.net/quick-start/</guid>
      <description>&lt;p&gt;Five minutes with each tool. First &lt;a href=&#34;https://bxm.net/download/&#34;&gt;download&lt;/a&gt; the archive for your system and put &lt;code&gt;bxm-canon&lt;/code&gt; and &lt;code&gt;bxm-memo&lt;/code&gt; on your &lt;code&gt;PATH&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;bxm-canon&#34;&gt;BXM Canon&lt;/h2&gt;&#xA;&lt;p&gt;Write the same data two ways and hash both:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;{&amp;#34;name&amp;#34;:&amp;#34;bxm&amp;#34;,&amp;#34;tags&amp;#34;:[&amp;#34;a&amp;#34;,&amp;#34;b&amp;#34;],&amp;#34;n&amp;#34;:3}&amp;#39;&lt;/span&gt; &amp;gt; a.json&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;{ &amp;#34;n&amp;#34;: 3, &amp;#34;tags&amp;#34;: [&amp;#34;a&amp;#34;, &amp;#34;b&amp;#34;], &amp;#34;name&amp;#34;: &amp;#34;bxm&amp;#34; }&amp;#39;&lt;/span&gt; &amp;gt; b.json&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;bxm-canon hash --text a.json&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;bxm-canon hash --text b.json&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The two hashes are the same, because both files hold the same value and Canon has one encoding for it.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Reference</title>
      <link>https://bxm.net/reference/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://bxm.net/reference/</guid>
      <description>&lt;p&gt;Every command and flag of both tools, and the Canon format in brief. The full format is in &lt;a href=&#34;https://github.com/softdevstudio/bxm/blob/main/spec/CANON.md&#34;&gt;spec/CANON.md&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;bxm-canon&#34;&gt;bxm-canon&lt;/h2&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;bxm-canon encode [FILE] [-o OUT]     Canon text (JSON) in, canonical bytes out&#xA;bxm-canon decode [FILE] [--pretty]   canonical bytes in, Canon text out&#xA;bxm-canon fmt [FILE] [--pretty]      text in, the one normal text form out&#xA;bxm-canon check FILE...              exit 0 only if every file is canonical bytes&#xA;bxm-canon hash [FILE] [--text]       SHA-256 of the canonical bytes&#xA;bxm-canon diff A B [--text]          paths that differ between two values&#xA;bxm-canon version&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;FILE&lt;/code&gt; defaults to standard input, and &lt;code&gt;-&lt;/code&gt; also means standard input. &lt;code&gt;--text&lt;/code&gt; tells &lt;code&gt;hash&lt;/code&gt; and &lt;code&gt;diff&lt;/code&gt; that the inputs are Canon text rather than canonical bytes. &lt;code&gt;-o&lt;/code&gt; writes to a file instead of standard output.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Use Cases</title>
      <link>https://bxm.net/use-cases/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://bxm.net/use-cases/</guid>
      <description>&lt;p&gt;Where BXM earns its place, with a worked case study for each. Every case study is a script in the &lt;a href=&#34;https://github.com/softdevstudio/bxm&#34;&gt;repository&lt;/a&gt; under &lt;code&gt;examples/case-studies&lt;/code&gt;. Its recorded output is in &lt;code&gt;test/results/case-studies&lt;/code&gt;, and you can run it again yourself.&lt;/p&gt;&#xA;&lt;h2 id=&#34;bxm-canon&#34;&gt;BXM Canon&lt;/h2&gt;&#xA;&lt;p&gt;&lt;strong&gt;Signatures and hashes across languages.&lt;/strong&gt; One service signs data and another checks it, each in its own language. With Canon both sides sign the same bytes, so the check only fails when the data changed. &lt;a href=&#34;https://bxm.net/one-order-built-in-python-javascript-and-by-hand-gives-three-json-hashes-and-one-canon-hash/&#34;&gt;One order built in Python, JavaScript and by hand&lt;/a&gt; gave three JSON hashes and one Canon hash. Python&amp;rsquo;s signature over its JSON failed in JavaScript, and the one over the Canon bytes passed.&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
