<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>http://debianws.lexgopc.com/wiki143/index.php?action=history&amp;feed=atom&amp;title=Serial_number_arithmetic</id>
	<title>Serial number arithmetic - Revision history</title>
	<link rel="self" type="application/atom+xml" href="http://debianws.lexgopc.com/wiki143/index.php?action=history&amp;feed=atom&amp;title=Serial_number_arithmetic"/>
	<link rel="alternate" type="text/html" href="http://debianws.lexgopc.com/wiki143/index.php?title=Serial_number_arithmetic&amp;action=history"/>
	<updated>2026-05-05T19:17:51Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.1</generator>
	<entry>
		<id>http://debianws.lexgopc.com/wiki143/index.php?title=Serial_number_arithmetic&amp;diff=1787532&amp;oldid=prev</id>
		<title>imported&gt;Mykhal: Undid revision 1192232333 by 102.90.47.204 (talk) - very misleading desc.</title>
		<link rel="alternate" type="text/html" href="http://debianws.lexgopc.com/wiki143/index.php?title=Serial_number_arithmetic&amp;diff=1787532&amp;oldid=prev"/>
		<updated>2024-03-08T22:28:43Z</updated>

		<summary type="html">&lt;p&gt;Undid revision 1192232333 by &lt;a href=&quot;/wiki143/index.php?title=Special:Contributions/102.90.47.204&quot; title=&quot;Special:Contributions/102.90.47.204&quot;&gt;102.90.47.204&lt;/a&gt; (&lt;a href=&quot;/wiki143/index.php?title=User_talk:102.90.47.204&amp;amp;action=edit&amp;amp;redlink=1&quot; class=&quot;new&quot; title=&quot;User talk:102.90.47.204 (page does not exist)&quot;&gt;talk&lt;/a&gt;) - very misleading desc.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;Many [[Protocol (computing)|protocols]] and [[algorithms]] require the serialization or enumeration of related entities. For example, a [[communication protocol]] must know whether some packet comes &amp;quot;before&amp;quot; or &amp;quot;after&amp;quot; some other packet. The [[IETF]] ([[Internet Engineering Task Force]]) {{IETF RFC|1982}} attempts to define &amp;quot;serial number arithmetic&amp;quot; for the purposes of manipulating and comparing these [[sequence number]]s. In short, when the absolute serial number value decreases by more than half of the maximum value (e.g. 128 in an 8-bit value), it is considered to be &amp;quot;after&amp;quot; the former, whereas other decreases are considered to be &amp;quot;before&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
This task is rather more complex than it might first appear, because most algorithms use fixed-size ([[Binary numeral system|binary]]) representations for sequence numbers. It is often important for the algorithm not to &amp;quot;break down&amp;quot; when the numbers become so large that they are incremented one last time and &amp;quot;wrap&amp;quot; around their maximum numeric ranges (go instantly from a large positive number to 0 or a large negative number). Some protocols choose to ignore these issues and simply use very large integers for their counters, in the hope that the program will be replaced (or they will retire) before the problem occurs (see [[Year 2000 problem|Y2K]]).&lt;br /&gt;
&lt;br /&gt;
Many communication protocols apply serial number arithmetic to packet sequence numbers in their implementation of a [[sliding window protocol]]. Some versions of TCP use [[Transmission Control Protocol#TCP timestamps | protection against wrapped sequence numbers (PAWS)]]. PAWS applies the same serial number arithmetic to packet timestamps, using the timestamp as an extension of the high-order bits of the sequence number.&amp;lt;ref&amp;gt;{{IETF RFC|1323}}: &amp;quot;TCP Extensions for High Performance&amp;quot;, section 4.2.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Operations on sequence numbers==&lt;br /&gt;
&lt;br /&gt;
Only addition of a small positive [[integer]] to a sequence number and comparison of two sequence numbers are discussed.&lt;br /&gt;
Only unsigned binary implementations are discussed, with an arbitrary size in bits noted throughout the RFC (and below) as &amp;quot;SERIAL_BITS&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===Addition===&lt;br /&gt;
&lt;br /&gt;
Adding an integer to a sequence number is simple unsigned integer addition, followed by unsigned [[modulo operation]] to bring the result back into range (usually implicit in the unsigned addition, on most architectures):&lt;br /&gt;
&lt;br /&gt;
: &amp;#039;&amp;#039;s&amp;#039;&amp;#039;&amp;lt;nowiki/&amp;gt;&amp;#039; = (&amp;#039;&amp;#039;s&amp;#039;&amp;#039; + &amp;#039;&amp;#039;n&amp;#039;&amp;#039;) modulo 2{{sup|SERIAL_BITS}}&lt;br /&gt;
&lt;br /&gt;
Addition of a value below 0 or above 2{{sup|SERIAL_BITS−1}} − 1 is undefined. Basically, adding values beyond this range will cause the resultant sequence number to &amp;quot;wrap&amp;quot;, and (often) result in a number that is considered &amp;quot;less than&amp;quot; the original sequence number.&lt;br /&gt;
&lt;br /&gt;
===Comparison===&lt;br /&gt;
&lt;br /&gt;
A means of comparing two sequence numbers &amp;#039;&amp;#039;i&amp;#039;&amp;#039;{{sub|1}} and &amp;#039;&amp;#039;i&amp;#039;&amp;#039;{{sub|2}} (the unsigned integer representations of sequence numbers &amp;#039;&amp;#039;s&amp;#039;&amp;#039;&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; and &amp;#039;&amp;#039;s&amp;#039;&amp;#039;&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;) is presented.&lt;br /&gt;
&lt;br /&gt;
Equality is defined as simple numeric equality.&lt;br /&gt;
&lt;br /&gt;
The algorithm presented for comparison is complex, having to take into account whether the first sequence number is close to the &amp;quot;end&amp;quot; of its range of values, and thus a smaller &amp;quot;wrapped&amp;quot; number may actually be considered &amp;quot;greater&amp;quot; than the first sequence number. Thus &amp;#039;&amp;#039;i&amp;#039;&amp;#039;{{sub|1}} is considered less than &amp;#039;&amp;#039;i&amp;#039;&amp;#039;{{sub|2}} only if&lt;br /&gt;
&lt;br /&gt;
: (&amp;#039;&amp;#039;i&amp;#039;&amp;#039;{{sub|1}} &amp;lt; &amp;#039;&amp;#039;i&amp;#039;&amp;#039;{{sub|2}} and &amp;#039;&amp;#039;i&amp;#039;&amp;#039;{{sub|2}} − &amp;#039;&amp;#039;i&amp;#039;&amp;#039;{{sub|1}} &amp;lt; 2{{sup|SERIAL_BITS−1}}) or&lt;br /&gt;
: (&amp;#039;&amp;#039;i&amp;#039;&amp;#039;{{sub|1}} &amp;gt; &amp;#039;&amp;#039;i&amp;#039;&amp;#039;{{sub|2}} and &amp;#039;&amp;#039;i&amp;#039;&amp;#039;{{sub|1}} − &amp;#039;&amp;#039;i&amp;#039;&amp;#039;{{sub|2}} &amp;gt; 2{{sup|SERIAL_BITS−1}})&lt;br /&gt;
&lt;br /&gt;
==Shortfalls==&lt;br /&gt;
&lt;br /&gt;
The algorithms presented by the RFC have at least one significant shortcoming: &lt;br /&gt;
there are sequence numbers for which comparison is undefined.&lt;br /&gt;
Since many algorithms are implemented independently by multiple independent cooperating parties,&lt;br /&gt;
it is often impossible to prevent all such situations from occurring.&lt;br /&gt;
&lt;br /&gt;
The authors of {{IETF RFC|1982}} acknowledge this without offering a general solution:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
While it would be possible to define the test in such a way that the&lt;br /&gt;
inequality would not have this surprising property, while being&lt;br /&gt;
defined for all pairs of values, such a definition would be&lt;br /&gt;
unnecessarily burdensome to implement, and difficult to understand,&lt;br /&gt;
and would still allow cases where&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
s1 &amp;lt; s2 and (s1 + 1) &amp;gt; (s2 + 1)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
which is just as non-intuitive.&lt;br /&gt;
   &lt;br /&gt;
Thus the problem case is left undefined, implementations are free to&lt;br /&gt;
return either result, or to flag an error, and users must take care&lt;br /&gt;
not to depend on any particular outcome.  Usually this will mean&lt;br /&gt;
avoiding allowing those particular pairs of numbers to co-exist.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Thus, it is often difficult or impossible to avoid all &amp;quot;undefined&amp;quot; comparisons of sequence numbers.&lt;br /&gt;
However, a relatively simple solution is available. By mapping the unsigned sequence numbers onto signed [[two&amp;#039;s complement]] arithmetic operations, every comparison of any sequence number is defined, and the comparison operation itself is dramatically simplified. All comparisons specified by the RFC retain their original truth values; only the formerly &amp;quot;undefined&amp;quot; comparisons are affected.&lt;br /&gt;
&lt;br /&gt;
==General solution==&lt;br /&gt;
&lt;br /&gt;
The {{IETF RFC|1982}} algorithm specifies that, for &amp;#039;&amp;#039;N&amp;#039;&amp;#039;-bit sequence numbers, there are 2&amp;lt;sup&amp;gt;&amp;#039;&amp;#039;N&amp;#039;&amp;#039;−1&amp;lt;/sup&amp;gt;&amp;amp;nbsp;−&amp;amp;nbsp;1 values considered &amp;quot;greater than&amp;quot; and 2&amp;lt;sup&amp;gt;&amp;#039;&amp;#039;N&amp;#039;&amp;#039;−1&amp;lt;/sup&amp;gt;&amp;amp;nbsp;−&amp;amp;nbsp;1 considered &amp;quot;less than&amp;quot;. Comparison against the remaining value (exactly 2&amp;lt;sup&amp;gt;&amp;#039;&amp;#039;N&amp;#039;&amp;#039;−1&amp;lt;/sup&amp;gt;-distant) is deemed to be &amp;quot;undefined&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Most modern hardware implements signed [[two&amp;#039;s complement]] binary arithmetic operations.&lt;br /&gt;
These operations are fully defined for the entire range of values for any operands they are given, since any &amp;#039;&amp;#039;N&amp;#039;&amp;#039;-bit binary number can contain 2&amp;lt;sup&amp;gt;&amp;#039;&amp;#039;N&amp;#039;&amp;#039;&amp;lt;/sup&amp;gt; distinct values, and since one of them is taken up by the value 0, there are an odd number of spots left for all the non-zero positive and negative numbers.&lt;br /&gt;
There is simply one more negative number representable than there are positive.&lt;br /&gt;
For example, a 16-bit 2&amp;#039;s complement value may contain numbers ranging from {{val|−32768}} to {{val|+32767}}.&lt;br /&gt;
&lt;br /&gt;
So, if we simply re-cast sequence numbers as 2&amp;#039;s complement integers and allow there to be one more sequence number considered &amp;quot;less than&amp;quot; than there are sequence numbers considered &amp;quot;greater than&amp;quot;, we should be able to use simple signed arithmetic comparisons instead of the logically incomplete formula proposed by the RFC.&lt;br /&gt;
&lt;br /&gt;
Here are some examples (in 16 bits, again), comparing some random sequence numbers, against the sequence number with the value 0:&lt;br /&gt;
&lt;br /&gt;
 unsigned    binary    signed&lt;br /&gt;
 sequence    value     distance&lt;br /&gt;
 --------    ------    --------&lt;br /&gt;
    32767 == 0x7FFF ==  32767&lt;br /&gt;
        1 == 0x0001 ==      1&lt;br /&gt;
        0 == 0x0000 ==      0&lt;br /&gt;
    65535 == 0xFFFF ==     −1 &lt;br /&gt;
    65534 == 0xFFFE ==     −2&lt;br /&gt;
    32768 == 0x8000 == −32768&lt;br /&gt;
&lt;br /&gt;
It is easy to see that the signed interpretation of the sequence numbers are in the correct order, so long as we &amp;quot;rotate&amp;quot; the sequence number in question so that its 0 matches up with the sequence number we are comparing it against. It turns out that this is simply done using an unsigned subtraction and simply interpreting the result as a signed two&amp;#039;s complement number. The result is the signed &amp;quot;distance&amp;quot; between the two sequence numbers. Once again, if &amp;lt;code&amp;gt;i1&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;i2&amp;lt;/code&amp;gt; are the unsigned binary representations of the sequence numbers &amp;#039;&amp;#039;s&amp;#039;&amp;#039;&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; and &amp;#039;&amp;#039;s&amp;#039;&amp;#039;&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;, the distance from &amp;#039;&amp;#039;s&amp;#039;&amp;#039;&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; to &amp;#039;&amp;#039;s&amp;#039;&amp;#039;&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt; is&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
distance = (signed)(i1 - i2)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
If distance is 0, the numbers are equal. If it is &amp;lt; 0, then &amp;#039;&amp;#039;s&amp;#039;&amp;#039;&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; is &amp;quot;less than&amp;quot; or &amp;quot;before&amp;quot; &amp;#039;&amp;#039;s&amp;#039;&amp;#039;&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;.&lt;br /&gt;
Simple, clean and efficient, and fully defined. However, not without surprises.&lt;br /&gt;
&lt;br /&gt;
All sequence number arithmetic must deal with &amp;quot;wrapping&amp;quot; of sequence numbers; the number 2&amp;lt;sup&amp;gt;&amp;#039;&amp;#039;N&amp;#039;&amp;#039;−1&amp;lt;/sup&amp;gt; is equidistant in both directions, in {{IETF RFC|1982}} sequence number terms. In our math, they are both considered to be &amp;quot;less than&amp;quot; each other:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
distance1 = (signed)(0x8000 - 0x0)    == (signed)0x8000 == -32768 &amp;lt; 0&lt;br /&gt;
distance2 = (signed)(0x0    - 0x8000) == (signed)0x8000 == -32768 &amp;lt; 0&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
This is obviously true for any two sequence numbers with distance of 0x8000 between them.&lt;br /&gt;
&lt;br /&gt;
Furthermore, implementing serial number arithmetic using two&amp;#039;s complement arithmetic implies serial numbers of a bit-length matching the machine&amp;#039;s integer sizes; usually 16-bit, 32-bit and 64-bit. Implementing 20-bit serial numbers needs shifts (assuming 32-bit ints):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
distance = (signed)((i1 &amp;lt;&amp;lt; 12) - (i2 &amp;lt;&amp;lt; 12))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
* [[Date windowing]]&lt;br /&gt;
*[[Lollipop sequence numbering]]&lt;br /&gt;
*[[Modular arithmetic]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
{{reflist}}&lt;br /&gt;
&lt;br /&gt;
==External links==&lt;br /&gt;
* {{IETF RFC|2182}}&lt;br /&gt;
* {{IETF RFC|1982}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Domain Name System]]&lt;br /&gt;
[[Category:Serial numbers]]&lt;/div&gt;</summary>
		<author><name>imported&gt;Mykhal</name></author>
	</entry>
</feed>