Network Working Group                                           J. Stone
Request for Comments: 3309                                      Stanford
Updates: 2960                                                 R. Stewart
Category: Standards                                        Cisco Systems
                                                                 D. Otis
                                                                SANlight
                                                          September 2002
        
Network Working Group                                           J. Stone
Request for Comments: 3309                                      Stanford
Updates: 2960                                                 R. Stewart
Category: Standards                                        Cisco Systems
                                                                 D. Otis
                                                                SANlight
                                                          September 2002
        

Stream Control Transmission Protocol (SCTP) Checksum Change

流控制传输协议(SCTP)校验和更改

Status of this Memo

本备忘录的状况

This document specifies an Internet standards track protocol for the Internet community, and requests discussion and suggestions for improvements. Please refer to the current edition of the "Internet Official Protocol Standards" (STD 1) for the standardization state and status of this protocol. Distribution of this memo is unlimited.

本文件规定了互联网社区的互联网标准跟踪协议,并要求进行讨论和提出改进建议。有关本协议的标准化状态和状态,请参考当前版本的“互联网官方协议标准”(STD 1)。本备忘录的分发不受限制。

Copyright Notice

版权公告

Copyright (C) The Internet Society (2002). All Rights Reserved.

版权所有(C)互联网协会(2002年)。版权所有。

Abstract

摘要

Stream Control Transmission Protocol (SCTP) currently uses an Adler-32 checksum. For small packets Adler-32 provides weak detection of errors. This document changes that checksum and updates SCTP to use a 32 bit CRC checksum.

流控制传输协议(SCTP)目前使用Adler-32校验和。对于小数据包,Adler-32提供微弱的错误检测。本文档更改该校验和并更新SCTP以使用32位CRC校验和。

Table of Contents

目录

   1 Introduction ...................................................  2
   2 Checksum Procedures ............................................  3
   3 Security Considerations.........................................  6
   4 IANA Considerations.............................................  6
   5 Acknowledgments ................................................  6
   6 References .....................................................  7
   Appendix .........................................................  9
   Authors' Addresses ............................................... 16
   Full Copyright Statement ......................................... 17
        
   1 Introduction ...................................................  2
   2 Checksum Procedures ............................................  3
   3 Security Considerations.........................................  6
   4 IANA Considerations.............................................  6
   5 Acknowledgments ................................................  6
   6 References .....................................................  7
   Appendix .........................................................  9
   Authors' Addresses ............................................... 16
   Full Copyright Statement ......................................... 17
        

1 Introduction

1导言

A fundamental weakness has been detected in SCTP's current Adler-32 checksum algorithm [STONE]. This document updates and replaces the Adler-32 checksum definition in [RFC 2960]. Note that there is no graceful transition mechanism for migrating to the new checksum. Implementations are expected to immediately switch to the new algorithm; use of the old algorithm is deprecated.

在SCTP当前的Adler-32校验和算法[STONE]中发现了一个基本缺陷。本文档更新并替换[RFC 2960]中的Adler-32校验和定义。请注意,没有优雅的转换机制可用于迁移到新的校验和。预期实现会立即切换到新算法;不推荐使用旧算法。

One requirement of an effective checksum is that it evenly and smoothly spreads its input packets over the available check bits.

有效校验和的一个要求是,它在可用校验位上均匀平滑地传播其输入数据包。

From an email from Jonathan Stone, who analyzed the Adler-32 as part of his doctoral thesis:

乔纳森·斯通(Jonathan Stone)在其博士论文中分析了Adler-32:

"Briefly, the problem is that, for very short packets, Adler32 is guaranteed to give poor coverage of the available bits. Don't take my word for it, ask Mark Adler. :-)

“简单地说,问题是,对于非常短的数据包,Adler32保证对可用位的覆盖率很低。不要相信我的话,问问Mark Adler.:-)

Adler-32 uses two 16-bit counters, s1 and s2. s1 is the sum of the input, taken as 8-bit bytes. s2 is a running sum of each value of s1. Both s1 and s2 are computed mod-65521 (the largest prime less than 2^16). Consider a packet of 128 bytes. The *most* that each byte can be is 255. There are only 128 bytes of input, so the greatest value which the s1 accumulator can have is 255 * 128 = 32640. So, for 128-byte packets, s1 never wraps. That is critical. Why?

Adler-32使用两个16位计数器s1和s2。s1是输入的总和,取为8位字节。s2是s1的每个值的运行总和。s1和s2均由mod-65521计算(最大素数小于2^16)。考虑一个128字节的数据包。每个字节的*最大*值为255。只有128字节的输入,因此s1累加器可以拥有的最大值是255*128=32640。因此,对于128字节的数据包,s1从不换行。这是至关重要的。为什么?

The key is to consider the distribution of the s1 values, over some distribution of the values of the individual input bytes in each packet. Because s1 never wraps, s1 is simply the sum of the individual input bytes. (Even Doug's trick of adding 0x5555 doesn't help here, and an even larger value doesn't really help: we can get at most one mod-65521 reduction.)

关键是考虑S1值的分布,超过每个分组中各个输入字节的值的分布。因为s1从不换行,s1只是单个输入字节的总和。(即使是Doug的添加0x5555的技巧在这里也没有帮助,更大的值也没有真正的帮助:我们最多可以得到一个mod-65521减少。)

Given the further assumption that the input bytes are drawn independently from some distribution (they probably aren't: for file system data, it's even worse than that!), the Central Limit Theorem tells us that that s1 will tend to have a normal distribution. That's bad: it tells us that the value of s1 will have hot-spots at around 128 times the mean of the input distribution: around 16k, assuming a uniform distribution. That's bad. We want the accumulator to wrap as many times as possible, so that the resulting sum has as close to a uniform distribution as possible. (I call this "fairness".)

进一步假设输入字节是独立于某些分布绘制的(它们可能不是:对于文件系统数据,甚至更糟!),中心极限定理告诉我们s1将趋向于正态分布。这是不好的:它告诉我们s1的值将有大约128倍于输入分布平均值的热点:大约16k,假设均匀分布。那太糟糕了。我们希望累加器尽可能多地进行包装,以便得到的总和尽可能接近均匀分布。(我称之为“公平”。)

So, for short packets, the Adler-32 s1 sum is guaranteed to be unfair. Why is that bad? It's bad because the space of valid packets -- input data, plus checksum values -- is also small. If all packets have checksum values very close to 32640, then the likelihood of even a 'small' error leaving a damaged packet with a valid checksum is higher than if all checksum values are equally likely."

因此,对于短分组,Adler-32 s1和肯定是不公平的。为什么那么糟糕?这很糟糕,因为有效数据包的空间——输入数据,加上校验和值——也很小。如果所有数据包的校验和值都非常接近32640,则即使是“小”错误,使用有效校验和留下损坏数据包的可能性也高于所有校验和值的可能性相同的情况。”

Due to this inherent weakness, exacerbated by the fact that SCTP will first be used as a signaling transport protocol where signaling messages are usually less than 128 bytes, a new checksum algorithm is specified by this document, replacing the current Adler-32 algorithm with CRC-32c.

由于SCTP将首先用作信令消息通常小于128字节的信令传输协议这一事实加剧了这一固有弱点,因此本文件规定了一种新的校验和算法,用CRC-32c替换当前的Adler-32算法。

1.1 Conventions
1.1 习俗

The keywords MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD,SHOULD NOT, RECOMMENDED, NOT RECOMMENDED, MAY, and OPTIONAL, when they appear in this document, are to be interpreted as described in [RFC2119].

本文件中出现的关键词必须、不得、必需、应、不应、应、不应、推荐、不推荐、可和可选时,应按照[RFC2119]中的说明进行解释。

Bit number order is defined in [RFC1700].

位号顺序在[RFC1700]中定义。

2 Checksum Procedures

2校验和程序

The procedures described in section 2.1 of this document MUST be followed, replacing the current checksum defined in [RFC2960].

必须遵循本文件第2.1节中描述的程序,替换[RFC2960]中定义的当前校验和。

Furthermore any references within [RFC2960] to Adler-32 MUST be treated as a reference to CRC-32c. Section 2.1 of this document describes the new calculation and verification procedures that MUST be followed.

此外,[RFC2960]中对Adler-32的任何引用必须视为对CRC-32c的引用。本文件第2.1节描述了必须遵循的新计算和验证程序。

2.1 Checksum Calculation
2.1 校验和计算

When sending an SCTP packet, the endpoint MUST strengthen the data integrity of the transmission by including the CRC-32c checksum value calculated on the packet, as described below.

当发送SCTP分组时,端点必须通过包括分组上计算的CRC-32c校验和值来加强传输的数据完整性,如下所述。

After the packet is constructed (containing the SCTP common header and one or more control or DATA chunks), the transmitter shall:

在构建数据包(包含SCTP公共报头和一个或多个控制或数据块)后,发送器应:

1) Fill in the proper Verification Tag in the SCTP common header and initialize the Checksum field to 0's.

1) 在SCTP公共标头中填写正确的验证标记,并将校验和字段初始化为0。

2) Calculate the CRC-32c of the whole packet, including the SCTP common header and all the chunks.

2) 计算整个数据包的CRC-32c,包括SCTP公共头和所有数据块。

3) Put the resulting value into the Checksum field in the common header, and leave the rest of the bits unchanged.

3) 将结果值放入公共标头的校验和字段中,并保持其余位不变。

When an SCTP packet is received, the receiver MUST first check the CRC-32c checksum:

当接收到SCTP数据包时,接收器必须首先检查CRC-32c校验和:

1) Store the received CRC-32c value,

1) 存储接收到的CRC-32c值,

2) Replace the 32 bits of the Checksum field in the received SCTP packet with all '0's and calculate a CRC-32c value of the whole received packet. And,

2) 用所有“0”替换接收到的SCTP数据包中校验和字段的32位,并计算整个接收数据包的CRC-32c值。和

3) Verify that the calculated CRC-32c value is the same as the received CRC-32c value. If not, the receiver MUST treat the packet as an invalid SCTP packet.

3) 验证计算出的CRC-32c值是否与接收到的CRC-32c值相同。否则,接收方必须将该数据包视为无效的SCTP数据包。

The default procedure for handling invalid SCTP packets is to silently discard them.

处理无效SCTP数据包的默认过程是以静默方式丢弃它们。

Any hardware implementation SHOULD be done in a way that is verifiable by the software.

任何硬件实现都应以软件可验证的方式进行。

We define a 'reflected value' as one that is the opposite of the normal bit order of the machine. The 32 bit CRC is calculated as described for CRC-32c and uses the polynomial code 0x11EDC6F41 (Castagnoli93) or x^32+x^28+x^27+x^26+x^25 +x^23+x^22+x^20+x^19+x^18+x^14+x^13+x^11+x^10+x^9+x^8+x^6+x^0. The CRC is computed using a procedure similar to ETHERNET CRC [ITU32], modified to reflect transport level usage.

我们将“反射值”定义为与机器的正常位顺序相反的值。按照CRC-32c的说明计算32位CRC,并使用多项式代码0x11EDC6F41(Castagnoli93)或x^32+x^28+x^27+x^26+x^25+x^23+x^22+x^20+x^19+x^18+x^14+x^13+x^11+x^10+x^9+x^8+x^6+x^0。CRC的计算过程与以太网CRC[ITU32]类似,经过修改以反映传输级别的使用情况。

CRC computation uses polynomial division. A message bit-string M is transformed to a polynomial, M(X), and the CRC is calculated from M(X) using polynomial arithmetic [Peterson 72].

CRC计算使用多项式除法。将消息比特串M转换为多项式M(X),并使用多项式算法从M(X)计算CRC[Peterson 72]。

When CRCs are used at the link layer, the polynomial is derived from on-the-wire bit ordering: the first bit 'on the wire' is the high-order coefficient. Since SCTP is a transport-level protocol, it cannot know the actual serial-media bit ordering. Moreover, different links in the path between SCTP endpoints may use different link-level bit orders.

当在链路层使用CRC时,多项式是从在线位顺序推导出来的:第一位“在线”是高阶系数。由于SCTP是一种传输级协议,它无法知道实际的串行媒体位顺序。此外,SCTP端点之间的路径中的不同链路可以使用不同的链路级比特顺序。

A convention must therefore be established for mapping SCTP transport messages to polynomials for purposes of CRC computation. The bit-ordering for mapping SCTP messages to polynomials is that bytes are taken most-significant first; but within each byte, bits are taken least-significant first. The first byte of the message provides the eight highest coefficients. Within each byte, the least-significant SCTP bit gives the most significant polynomial coefficient within

因此,必须建立一种约定,将SCTP传输消息映射到多项式,以便进行CRC计算。将SCTP消息映射到多项式的位顺序是首先取最重要的字节;但在每个字节中,位首先被取为最低有效位。消息的第一个字节提供八个最高系数。在每个字节内,最低有效SCTP位给出了该字节内最高有效多项式系数

that byte, and the most-significant SCTP bit is the least significant polynomial coefficient in that byte. (This bit ordering is sometimes called 'mirrored' or 'reflected' [Williams93].) CRC polynomials are to be transformed back into SCTP transport-level byte values, using a consistent mapping.

该字节,最高有效SCTP位是该字节中最低有效多项式系数。(这种位顺序有时称为“镜像”或“反射”[Williams93])CRC多项式将使用一致映射转换回SCTP传输级字节值。

The SCTP transport-level CRC value should be calculated as follows:

SCTP传输级CRC值的计算如下:

- CRC input data are assigned to a byte stream, numbered from 0 to N-1.

- CRC输入数据分配给字节流,编号从0到N-1。

- the transport-level byte-stream is mapped to a polynomial value. An N-byte PDU with j bytes numbered 0 to N-1, is considered as coefficients of a polynomial M(x) of order 8N-1, with bit 0 of byte j being coefficient x^(8(N-j)-8), bit 7 of byte j being coefficient x^(8(N-j)-1).

- 传输级字节流映射到多项式值。具有编号为0到N-1的j字节的N字节PDU被视为8N-1阶多项式M(x)的系数,其中字节j的位0为系数x^(8(N-j)-8),字节j的位7为系数x^(8(N-j)-1)。

- the CRC remainder register is initialized with all 1s and the CRC is computed with an algorithm that simultaneously multiplies by x^32 and divides by the CRC polynomial.

- CRC余数寄存器用所有1初始化,CRC用同时乘以x^32和除以CRC多项式的算法计算。

- the polynomial is multiplied by x^32 and divided by G(x), the generator polynomial, producing a remainder R(x) of degree less than or equal to 31.

- 该多项式乘以x^32,再除以生成多项式G(x),得到一个小于或等于31次的余数R(x)。

- the coefficients of R(x) are considered a 32 bit sequence.

- R(x)的系数被认为是一个32位序列。

- the bit sequence is complemented. The result is the CRC polynomial.

- 位序列被补充。结果是CRC多项式。

- The CRC polynomial is mapped back into SCTP transport-level bytes. Coefficient of x^31 gives the value of bit 7 of SCTP byte 0, the coefficient of x^24 gives the value of bit 0 of byte 0. The coefficient of x^7 gives bit 7 of byte 3 and the coefficient of x^0 gives bit 0 of byte 3. The resulting four-byte transport-level sequence is the 32-bit SCTP checksum value.

- CRC多项式被映射回SCTP传输级字节。x^31的系数给出了SCTP字节0的第7位的值,x^24的系数给出了字节0的第0位的值。x^7的系数给出字节3的第7位,x^0的系数给出字节3的第0位。产生的四字节传输级序列是32位SCTP校验和值。

IMPLEMENTATION NOTE: Standards documents, textbooks, and vendor literature on CRCs often follow an alternative formulation, in which the register used to hold the remainder of the long-division algorithm is initialized to zero rather than all-1s, and instead the first 32 bits of the message are complemented. The long-division algorithm used in our formulation is specified, such that the the initial multiplication by 2^32 and the long-division are combined into one simultaneous operation. For such algorithms, and for messages longer than 64 bits, the two specifications are precisely equivalent. That equivalence is the intent of this document.

实施说明:关于CRC的标准文件、教科书和供应商文献通常遵循另一种表述,其中用于保存长除法算法剩余部分的寄存器初始化为零,而不是全部1,并补充消息的前32位。在我们的公式中使用的长除法是指定的,这样初始2^32的乘法和长除法被合并成一个同时的运算。对于此类算法,以及长度超过64位的消息,这两种规范完全等效。该等效性是本文件的目的。

Implementors of SCTP are warned that both specifications are to be found in the literature, sometimes with no restriction on the long-division algorithm. The choice of formulation in this document is to permit non-SCTP usage, where the same CRC algorithm may be used to protect messages shorter than 64 bits.

SCTP的实现者被警告,这两个规范都可以在文献中找到,有时对长除法算法没有限制。本文件中的公式选择允许非SCTP使用,其中相同的CRC算法可用于保护短于64位的消息。

If SCTP could follow link level CRC use, the CRC would be computed over the link-level bit-stream. The first bit on the link mapping to the highest-order coefficient, and so on, down to the last link-level bit as the lowest-order coefficient. The CRC value would be transmitted immediately after the input message as a link-level 'trailer'. The resulting link-level bit-stream would be (M(X)x) * x^32) + (M(X)*x^32))/ G(x), which is divisible by G(X). There would thus be a constant CRC remainder for 'good' packets. However, given that implementations of RFC 2960 have already proliferated, the IETF discussions considered that the benefit of a 'trailer' CRC did not outweigh the cost of making a very large change in the protocol processing. Further, packets accepted by the SCTP 'header' CRC are in one-to-one correspondence with packets accepted by a modified procedure using a 'trailer' CRC value, and where the SCTP common checksum header is set to zero on transmission and is received as zero.

如果SCTP可以遵循链路级CRC使用,则CRC将在链路级比特流上计算。链接上的第一位映射到最高阶系数,依此类推,直到最后一个链接级别的位作为最低阶系数。CRC值将在输入消息之后立即作为链路级“拖车”传输。得到的链路级比特流将是(M(X)X)*X^32)+(M(X)*X^32))/G(X),它可以被G(X)整除。因此,“好”数据包将有一个恒定的CRC余数。然而,鉴于RFC 2960的实现已经激增,IETF的讨论认为,“拖车”CRC的好处并不超过在协议处理中进行非常大的更改的成本。此外,SCTP“报头”CRC接受的分组与使用“拖车”CRC值的修改过程接受的分组一一对应,其中SCTP公共校验和报头在传输时被设置为零,并且被接收为零。

There may be a computational advantage in validating the Association against the Verification Tag, prior to performing a checksum, as invalid tags will result in the same action as a bad checksum in most cases. The exceptions for this technique would be INIT and some SHUTDOWN-COMPLETE exchanges, as well as a stale COOKIE-ECHO. These special case exchanges must represent small packets and will minimize the effect of the checksum calculation.

在执行校验和之前,根据验证标记验证关联可能具有计算优势,因为在大多数情况下,无效标记将导致与错误校验和相同的操作。这种技术的例外情况是INIT和一些关机完成的交换,以及陈旧的COOKIE-ECHO。这些特殊情况交换必须表示小数据包,并将校验和计算的影响降至最低。

3 Security Considerations

3安全考虑

In general, the security considerations of RFC 2960 apply to the protocol with the new checksum as well.

一般来说,RFC 2960的安全考虑也适用于具有新校验和的协议。

4 IANA Considerations

4 IANA考虑因素

There are no IANA considerations required in this document.

本文件中不需要IANA注意事项。

5 Acknowledgments

5致谢

The authors would like to thank the following people that have provided comments and input on the checksum issue:

作者要感谢以下就校验和问题提供评论和意见的人士:

Mark Adler, Ran Atkinson, Stephen Bailey, David Black, Scott Bradner, Mikael Degermark, Laurent Glaude, Klaus Gradischnig, Alf Heidermark, Jacob Heitz, Gareth Kiely, David Lehmann, Allision Mankin, Lyndon Ong, Craig Partridge, Vern Paxson, Kacheong Poon, Michael Ramalho, David Reed, Ian Rytina, Hanns Juergen Schwarzbauer, Chip Sharp, Bill Sommerfeld, Michael Tuexen, Jim Williams, Jim Wendt, Michael Welzl, Jonathan Wood, Lloyd Wood, Qiaobing Xie, La Monte Yarroll.

马克·阿德勒、冉·阿特金森、斯蒂芬·贝利、大卫·布莱克、斯科特·布拉德纳、米凯尔·德格马克、劳伦特·劳德、克劳斯·格拉迪施尼格、阿尔夫·海德马克、雅各布·海茨、加雷思·基利、大卫·莱曼、阿利森·曼金、林登·翁、克雷格·帕特里奇、弗恩·帕克森、卡昌潘、迈克尔·拉马霍、大卫·里德、伊恩·雷蒂娜、汉斯·朱尔根·施瓦茨鲍尔、奇普、,比尔·索末菲、迈克尔·图克森、吉姆·威廉姆斯、吉姆·温特、迈克尔·韦尔兹尔、乔纳森·伍德、劳埃德·伍德、谢乔冰、拉蒙特·雅罗。

Special thanks to Dafna Scheinwald, Julian Satran, Pat Thaler, Matt Wakeley, and Vince Cavanna, for selection criteria of polynomials and examination of CRC polynomials, particularly CRC-32c [Castagnoli93].

特别感谢Dafna Scheinwald、Julian Satran、Pat Thaler、Matt Wakeley和Vince Cavanna对多项式的选择标准和CRC多项式的检查,特别是CRC-32c[Castagnoli93]。

Special thanks to Mr. Ross Williams and his document [Williams93]. This non-formal perspective on software aspects of CRCs furthered understanding of authors previously unfamiliar with CRC computation. More formal treatments of [Blahut 94] or [Peterson 72], was also essential.

特别感谢罗斯·威廉姆斯先生及其文件[Williams93]。这种对CRC软件方面的非形式化观点加深了先前不熟悉CRC计算的作者的理解。对[Blahut 94]或[Peterson 72]进行更正式的治疗也很重要。

6 References

6参考文献

[Castagnoli93] G. Castagnoli, S. Braeuer and M. Herrman, "Optimization of Cyclic Redundancy-Check Codes with 24 and 32 Parity Bits", IEEE Transactions on Communications, Vol. 41, No. 6, June 1993

[Castagnoli93]G.Castagnoli,S.Braeuer和M.Herrman,“具有24和32奇偶校验位的循环冗余校验码的优化”,IEEE通信事务,第41卷,第6期,1993年6月

[McKee75] H. McKee, "Improved {CRC} techniques detects erroneous leading and trailing 0's in transmitted data blocks", Computer Design Volume 14 Number 10 Pages 102-4,106, October 1975

[McKee75]H.McKee,“改进的{CRC}技术检测传输数据块中的错误前导和尾随0”,计算机设计卷14第10卷第102-4106页,1975年10月

[RFC1700] Reynolds, J. and J. Postel, "ASSIGNED NUMBERS", RFC 1700, October 1994.

[RFC1700]Reynolds,J.和J.Postel,“分配的数字”,RFC1700,1994年10月。

[RFC2026] Bradner, S., "The Internet Standards Process -- Revision 3", BCP 9, RFC 2026, October 1996.

[RFC2026]Bradner,S.,“互联网标准过程——第3版”,BCP 9,RFC 2026,1996年10月。

[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.

[RFC2119]Bradner,S.,“RFC中用于表示需求水平的关键词”,BCP 14,RFC 2119,1997年3月。

[RFC2960] Stewart, R., Xie, Q., Morneault, K., Sharp, C., Schwarzbauer, H., Taylor, T., Rytina, I., Kalla, M., Zhang, L. and V. Paxson, "Stream Control Transmission Protocol," RFC 2960, October 2000.

[RFC2960]Stewart,R.,Xie,Q.,Morneault,K.,Sharp,C.,Schwarzbauer,H.,Taylor,T.,Rytina,I.,Kalla,M.,Zhang,L.和V.Paxson,“流控制传输协议”,RFC 29602000年10月。

[ITU32] ITU-T Recommendation V.42, "Error-correcting procedures for DCEs using asynchronous-to-synchronous conversion", section 8.1.1.6.2, October 1996.

[ITU32]ITU-T建议V.42,“使用异步到同步转换的DCE纠错程序”,第8.1.1.6.2节,1996年10月。

7.1 Informative References
7.1 资料性引用

[STONE] Stone, J., "Checksums in the Internet", Doctoral dissertation - August 2001.

[STONE]STONE,J.,“互联网中的校验和”,博士论文-2001年8月。

[Williams93] Williams, R., "A PAINLESS GUIDE TO CRC ERROR DETECTION ALGORITHMS" - Internet publication, August 1993, http://www.geocities.com/SiliconValley/Pines/ 8659/crc.htm.

[Williams93]Williams,R.,“CRC错误检测算法的无痛指南”-互联网出版物,1993年8月,http://www.geocities.com/SiliconValley/Pines/ 8659/crc.htm。

[Blahut 1994] R.E. Blahut, Theory and Practice of Error Control Codes, Addison-Wesley, 1994.

[Blahut 1994]R.E.Blahut,差错控制码的理论与实践,Addison-Wesley,1994。

[Easics 2001] http://www.easics.be/webtools/crctool. Online tools for synthesis of CRC Verilog and VHDL.

[Easics 2001]http://www.easics.be/webtools/crctool. 用于CRC Verilog和VHDL综合的在线工具。

[Feldmeier 95] David C. Feldmeier, Fast software implementation of error detection codes, IEEE Transactions on Networking, vol 3 no 6, pp 640-651, December, 1995.

[Feldmeier 95]David C.Feldmeier,错误检测代码的快速软件实现,IEEE网络交易,第3卷第6期,第640-651页,1995年12月。

[Glaise 1997] R. J. Glaise, A two-step computation of cyclic redundancy code CRC-32 for ATM networks, IBM Journal of Research and Development} vol 41 no 6, 1997. http://www.research.ibm.com/journal/rd/416/ glaise.html.

[Glaise 1997]R.J.Glaise,ATM网络循环冗余码CRC-32的两步计算,IBM研究与发展杂志}第41卷第6期,1997年。http://www.research.ibm.com/journal/rd/416/ glaise.html。

[Prange 1957] E. Prange, Cyclic Error-Correcting codes in two symbols, Technical report AFCRC-TN-57-103, Air Force Cambridge Research Center, Cambridge, Mass. 1957.

[Prange 1957]E.Prange,双符号循环纠错码,技术报告AFCRC-TN-57-103,空军剑桥研究中心,马萨诸塞州剑桥。1957

[Peterson 1972] W. W. Peterson and E.J Weldon, Error Correcting Codes, 2nd. edition, MIT Press, Cambridge, Massachusetts.

[Peterson 1972]W.W.Peterson和E.J Weldon,纠错码,第2期。麻省理工学院出版社,马萨诸塞州剑桥。

[Shie2001] Ming-Der Shieh et. al, A Systematic Approach for Parallel CRC Computations. Journal of Information Science and Engineering, Vol.17 No.3, pp.445-461

[Shie2001]Ming Der Shieh等人,并行CRC计算的系统方法。《信息科学与工程杂志》,第17卷第3期,第445-461页

[Sprachman2001] Michael Sprachman, Automatic Generation of Parallel CRC Circuits, IEEE Design & Test May-June 2001

[Sprachman 2001]Michael Sprachman,并行CRC电路的自动生成,IEEE设计与测试,2001年5月至6月

Appendix

附录

This appendix is for information only and is NOT part of the standard.

本附录仅供参考,不属于本标准的一部分。

The anticipated deployment of SCTP ranges over several orders of magnitude of link speed: from cellular-power telephony devices at tens of kilobits, to local links at tens of gigabits. Implementors of SCTP should consider their link speed and choose, from the wide range of CRC implementations, one which matches their own design point for size, cost, and throughput. Many techniques for computing CRCs are known. This Appendix surveys just a few, to give a feel for the range of techniques available.

SCTP的预期部署范围包括几个数量级的链路速度:从数十千位的蜂窝电话设备到数十千兆位的本地链路。SCTP的实现者应该考虑它们的链路速度,并从CRC实现的广泛范围内选择一个与它们自己的设计点匹配的大小、成本和吞吐量。许多计算CRC的技术是已知的。本附录仅调查了一些,以了解可用技术的范围。

CRCs are derived from early work by Prange in the 1950s [Prange 57]. The theory underlying CRCs and choice of generator polynomial can be introduced by either the theory of Galois fields [Blahut 94] or as ideals of an algebra over cyclic codes [cite Peterson 72].

CRC源于20世纪50年代Prange的早期工作[Prange 57]。CRC的基本理论和生成器多项式的选择可以通过伽罗瓦域理论[Blahut 94]或循环码代数的理想[cite Peterson 72]来介绍。

One of the simplest techniques is direct bit-serial hardware implementations, using the generator polynomial as the taps of a linear feedback shift register (LSFR). LSFR computation follows directly from the mathematics, and is generally attributed to Prange. Tools exist which, a CRC generator polynomial, will produce synthesizable Verilog code for CRC hardware [Easics 2001].

最简单的技术之一是直接位串行硬件实现,使用生成器多项式作为线性反馈移位寄存器(LSFR)的抽头。LSFR计算直接来自数学,通常归因于Prange。现有的工具(CRC生成器多项式)将为CRC硬件生成可合成的Verilog代码[Easics 2001]。

   Since LSFRs do not scale well in speed, a variety of other techniques
   have been explored.  One technique exploits the fact that the divisor
   of the polynomial long-division, G, is known in advance.  It is thus
   possible to pre-compute lookup tables giving the polynomial remainder
   of multiple input bits --- typically 2, 4, or 8 bits of input at a
   time.  This technique can be used either in software or in hardware.
   Software to compute lookup tables yielding 2, 4, or 8 bits of result
   is freely available. [Williams93]
        
   Since LSFRs do not scale well in speed, a variety of other techniques
   have been explored.  One technique exploits the fact that the divisor
   of the polynomial long-division, G, is known in advance.  It is thus
   possible to pre-compute lookup tables giving the polynomial remainder
   of multiple input bits --- typically 2, 4, or 8 bits of input at a
   time.  This technique can be used either in software or in hardware.
   Software to compute lookup tables yielding 2, 4, or 8 bits of result
   is freely available. [Williams93]
        

For multi-gigabit links, the above techniques may still not be fast enough. One technique for computing CRCS at OC-48 rates is 'two-stage' CRC computation [Glaise 1997]. Here, some multiple of G(x), G(x)H(x), is chosen so as to minimize the number of nonzero coefficients, or weight, of the product G(x)H(x). The low weight of the product polynomial makes it susceptible to efficient hardware divide-by-constant implementations. This first stage gives M(x)/ (G(x)H(x)), as its result. The second stage then divides the result of the first stage by H(x), yielding (M(x)/(G(x)H(x)))/H(x). If H(x) is also relatively prime to G(x), this gives M(x)/G(x). Further developments on this approach can be found in [Shie2001] and [Sprachman2001].

对于千兆链路,上述技术可能仍然不够快。以OC-48速率计算CRC的一种技术是“两阶段”CRC计算[Glaise 1997]。这里,选择G(x)的一些倍数,G(x)H(x),以便最小化乘积G(x)H(x)的非零系数或权重的数目。乘积多项式的低权重使得它容易受到高效硬件除以常量实现的影响。第一阶段的结果是M(x)/(G(x)H(x))。然后,第二阶段将第一阶段的结果除以H(x),得到(M(x)/(G(x)H(x))/H(x)。如果H(x)也是G(x)的相对素数,则得到M(x)/G(x。该方法的进一步发展可在[Shie2001]和[2001]中找到。

The literature also includes a variety of software CRC implementations. One approach is to use a carefully-tuned assembly code for direct polynomial division. [Feldmeier 95] reports that for low-weight polynomials, tuned polynomial arithmetic gives higher throughput than table-lookup algorithms. Even within table-lookup algorithms, the size of the table can be tuned, either for total cache footprint, or (for space-restricted environments) to minimize total size.

文献还包括各种软件CRC实现。一种方法是使用经过仔细调整的汇编代码进行直接多项式除法。[Feldmeier 95]报告称,对于低权重多项式,调优多项式算法比表查找算法具有更高的吞吐量。即使在表查找算法中,也可以调整表的大小,以获得总缓存占用空间,或者(对于空间受限的环境)最小化总大小。

Implementors should keep in mind, the bit ordering described in Section 2: the ordering of bits within bytes for computing CRCs in SCTP is the least significant bit of each byte is the most-significant polynomial coefficient(and vice-versa). This 'reflected' SCTP CRC bit ordering matches on-the-wire bit order for Ethernet and other serial media, but is the reverse of traditional Internet bit ordering.

实施者应记住,第2节:用于计算SCTP中CRC的字节内位顺序中描述的位顺序是每个字节的最低有效位是最高有效多项式系数(反之亦然)。这种“反映”的SCTP CRC位顺序与以太网和其他串行媒体的有线位顺序匹配,但与传统的互联网位顺序相反。

One technique to accommodate this bit-reversal can be explained as follows: sketch out a hardware implementation, assuming the bits are in CRC bit order; then perform a left-to-right inversion (mirror image) on the entire algorithm. (We defer, for a moment, the issue of byte order within words.) Then compute that "mirror image" in software. The CRC from the "mirror image" algorithm will be the bit-reversal of a correct hardware implementation. When the link-level media sends each byte, the byte is sent in the reverse of the host CPU bit-order. Serialization of each byte of the "reflected" CRC value re-reverses the bit order, so in the end, each byte will be transmitted on-the-wire in the specified bit order.

一种适应这种位反转的技术可以解释如下:勾画出一个硬件实现,假设位是CRC位顺序;然后对整个算法执行从左到右的反转(镜像)。(我们暂时推迟了字内字节顺序的问题。)然后在软件中计算“镜像”。来自“镜像”算法的CRC将是正确硬件实现的位反转。链路级介质发送每个字节时,该字节的发送顺序与主机CPU位顺序相反。“反射”CRC值的每个字节的序列化都会重新反转位顺序,因此最终,每个字节都将以指定的位顺序在导线上传输。

The following non-normative sample code is taken from an open-source CRC generator [Williams93], using the "mirroring" technique and yielding a lookup table for SCTP CRC32-c with 256 entries, each 32 bits wide. While neither especially slow nor especially fast, as software table-lookup CRCs go, it has the advantage of working on both big-endian and little-endian CPUs, using the same (host-order) lookup tables, and using only the pre-defined ntohl() and htonl() operations. The code is somewhat modified from [Williams93], to ensure portability between big-endian and little-endian architectures. (Note that if the byte endian-ness of the target architecture is known to be little-endian the final bit-reversal and byte-reversal steps can be folded into a single operation.)

以下非规范性示例代码取自开源CRC生成器[Williams93],使用“镜像”技术并生成一个包含256个条目的SCTP CRC32-c查找表,每个条目宽32位。虽然软件查表CRC既不特别慢,也不特别快,但它的优点是使用相同的(主机顺序)查表,并且只使用预定义的ntohl()和htonl()操作,同时在大端和小端CPU上工作。该代码在某种程度上是从[Williams93]修改而来的,以确保big-endian和little-endian架构之间的可移植性。(请注意,如果已知目标体系结构的字节结束符为小结束符,则最终的位反转和字节反转步骤可以折叠为单个操作。)

/*************************************************************/
/* Note Definition for Ross Williams table generator would   */
/* be: TB_WIDTH=4, TB_POLLY=0x1EDC6F41, TB_REVER=TRUE        */
/* For Mr. Williams direct calculation code use the settings */
/* cm_width=32, cm_poly=0x1EDC6F41, cm_init=0xFFFFFFFF,      */
/* cm_refin=TRUE, cm_refot=TRUE, cm_xorort=0x00000000        */
/*************************************************************/
        
/*************************************************************/
/* Note Definition for Ross Williams table generator would   */
/* be: TB_WIDTH=4, TB_POLLY=0x1EDC6F41, TB_REVER=TRUE        */
/* For Mr. Williams direct calculation code use the settings */
/* cm_width=32, cm_poly=0x1EDC6F41, cm_init=0xFFFFFFFF,      */
/* cm_refin=TRUE, cm_refot=TRUE, cm_xorort=0x00000000        */
/*************************************************************/
        
/* Example of the crc table file */
#ifndef __crc32cr_table_h__
#define __crc32cr_table_h__
        
/* Example of the crc table file */
#ifndef __crc32cr_table_h__
#define __crc32cr_table_h__
        
#define CRC32C_POLY 0x1EDC6F41
#define CRC32C(c,d) (c=(c>>8)^crc_c[(c^(d))&0xFF])
        
#define CRC32C_POLY 0x1EDC6F41
#define CRC32C(c,d) (c=(c>>8)^crc_c[(c^(d))&0xFF])
        

unsigned long crc_c[256] = { 0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L, 0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL, 0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL, 0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L, 0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL, 0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L, 0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L, 0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL, 0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL, 0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L, 0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L, 0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL, 0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L, 0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL, 0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL, 0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L, 0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L, 0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L, 0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L, 0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L, 0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L, 0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L, 0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L, 0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L, 0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L, 0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L, 0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L, 0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L, 0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L, 0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L, 0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L,

无符号长crc_c[256]=[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 7 7 7 A79A7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1111111111111111111福福1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1,0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 10 10 10 10 10 10 10 7 7 7 7 7 7 7 7 7 7 7 7 7 7,0 0 0 0 0 0 5 5 5 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 7BBCEF57L,0x4E4DFBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBD6D6D6D60DDDL,0xD2D20D66D6D6D6D6D6D6D6D6D6D6D6D6D6D6DDDL,0xC16,0xC18686861,0xC186fe2929L,0xC186FE29L,0xC18629L,0xC186FE29L,0xC18629L,0xC129L,0xC18629L,0xC18629L,0xC18629L,0xC18629L,0xC18629L,0xC29L,0xC29L,0x33ED7L,0x33LL05125比如,0x5B016189L,0xAA96A8,0xAA8 8 8 8 8 8 8 8 8 8 8 8 1,0xA8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 AAAAAAAA333333AAAAAA3333333333铝,8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8,0x5125个数据层,0xA34EE55500L,0xB01EA24L,0x42752927L,0x96BF4CCL,0x64D4CECFL,0x778433BL,0x773 333BL,0x3-3333333333333D4-D4-D4-CCL,0x64D4-D4-D4-CECFCFCFFL,0x777777843-33BL3-33BL3-3BL,0x77848433333BL,0x8-33BL10,0x8510,0x85EFbebebe3-333BL,0x8510,0x85Ebebebebebebe381,0x8,0x8510,0x85Ebebebebebebebe38L,0x8,0x8,0x8-38L,0x85勒勒勒勒勒勒勒勒勒留留留留留留留留留留留留,0x8,4bb5al,0xF84F3859L、0x2C855CB2L、0xDEEEDB1L、0xCDBE2C45L、0x3FD5AF46L、0x7198540DL、0x83F3D70EL、0x90A324FAL、0x62C8A7F9L、0xB602C312L、0x44694011L、0x5739B3E5L、0xA55230E6L、0xFB410CC2L、0x092A8FC1L、0x1A7A7C35L、0xE811F36L、,

0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L, 0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL, 0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L, 0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L, 0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL, 0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L, 0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL, 0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL, 0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L, 0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L, 0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL, 0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL, 0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L, 0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL, 0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L, 0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L, 0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL, 0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L, 0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL, 0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL, 0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L, 0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL, 0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L, 0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L, 0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL, 0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL, 0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L, 0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L, 0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL, 0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L, 0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL, 0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL, 0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L, };

0x2F8B8B77B414141414141414141414141414141414141414141414141404040404141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414040404040404010、101010101010101010101010101010101010101010101010101010101010777777777777777777777777777777777777777777777777777777777LLLLLL4040404041414141414141414141414141414141414141414141414141414141414141414141414141E80BL,0xB4091BFLL,0x466298FCL、0x1871A4D8L、0xEA1A27DBL、0xF94AD42FL、0x0B21572CL、0xDFEB33C7L、0x2D80B0C4L、0x3ED04330L、0xCCBBC033L、0xA24BB5A6L、0x502036A5L、0x4370C551L、0xB11B4652L、0x65D122B9L、0x97BAA11BAAL、0x84EA524EL、0x7681D14DL、0x2892ED69L、0xDAF96E6AL、0xC9AD9EL、0x3BC218D9D9L、0xB18B7F897L、0x28927F9L、0x897F9L、0x637F9L、,比如,0x87E6666D5L,0x94B49494949414141414141414141414141L,0x94B4949494941414141414141414141414141414141414141414141L,0x94B4949414141414141414141414141414141414141414141414141414141BBBB494949B49B49494141411L,0x6664B49B49B49B49B49B49B49B49B49494949B4141414111111111L,0x66414141414141414141414141414141LLLLLLLLLL,0x66B4,0x666,0x66B404040404040404040404040404040BBB49B49BB49B49B41414141414141414141414141414141414141414141CL,0x66FF599E3L,0x9D9E9AE0L,0x9E9E9E000A00L,0xD3D310 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 F05L,0x6个B8273D6L,0x88D28022个L,0x7个AB82808022个L,0x7个AB8080808022个L,0x7个AB9021个AB90321L,0x7个AE73676个卡尔,0xAE7367卡尔,0x55c6个C16个C16个C16个C16个C16个C16个,0x6个6个C16个C16个C16个C16个C16个C16个C16个C16个C16个C16,0x6个C16个C16个C16个L,0x9个B6个B9个B8个B8个B8个B8个B8个B8个B8个B828个B8个C16个C16个16161616 16 16 16 16 16 16 16,0x6个C16个C16个161616 16 16 16 16,0x7个L,0x7个L,0x7个L,0x7个808080808080808052L,0xAD7D5351L,};

#endif

#恩迪夫

 /* Example of table build routine */
        
 /* Example of table build routine */
        
#include <stdio.h>
#include <stdlib.h>
        
#include <stdio.h>
#include <stdlib.h>
        

#define OUTPUT_FILE "crc32cr.h" #define CRC32C_POLY 0x1EDC6F41L FILE *tf;

#定义输出文件“crc32cr.h”#定义CRC32C#POLY 0x1EDC6F41L文件*tf;

unsigned long
reflect_32 (unsigned long b)
{
  int i;
  unsigned long rw = 0L;
        
unsigned long
reflect_32 (unsigned long b)
{
  int i;
  unsigned long rw = 0L;
        
  for (i = 0; i < 32; i++){
      if (b & 1)
        rw |= 1 << (31 - i);
      b >>= 1;
  }
  return (rw);
}
        
  for (i = 0; i < 32; i++){
      if (b & 1)
        rw |= 1 << (31 - i);
      b >>= 1;
  }
  return (rw);
}
        
unsigned long
build_crc_table (int index)
{
  int i;
  unsigned long rb;
        
unsigned long
build_crc_table (int index)
{
  int i;
  unsigned long rb;
        

rb = reflect_32 (index);

rb=反映32(指数);

  for (i = 0; i < 8; i++){
      if (rb & 0x80000000L)
       rb = (rb << 1) ^ CRC32C_POLY;
      else
       rb <<= 1;
  }
  return (reflect_32 (rb));
}
        
  for (i = 0; i < 8; i++){
      if (rb & 0x80000000L)
       rb = (rb << 1) ^ CRC32C_POLY;
      else
       rb <<= 1;
  }
  return (reflect_32 (rb));
}
        
main ()
{
  int i;
        
main ()
{
  int i;
        
  printf ("\nGenerating CRC-32c table file <%s>\n", OUTPUT_FILE);
  if ((tf = fopen (OUTPUT_FILE, "w")) == NULL){
      printf ("Unable to open %s\n", OUTPUT_FILE);
      exit (1);
  }
  fprintf (tf, "#ifndef __crc32cr_table_h__\n");
  fprintf (tf, "#define __crc32cr_table_h__\n\n");
  fprintf (tf, "#define CRC32C_POLY 0x%08lX\n", CRC32C_POLY);
  fprintf (tf, "#define CRC32C(c,d) (c=(c>>8)^crc_c[(c^(d))&0xFF])\n");
  fprintf (tf, "\nunsigned long  crc_c[256] =\n{\n");
  for (i = 0; i < 256; i++){
      fprintf (tf, "0x%08lXL, ", build_crc_table (i));
      if ((i & 3) == 3)
        
  printf ("\nGenerating CRC-32c table file <%s>\n", OUTPUT_FILE);
  if ((tf = fopen (OUTPUT_FILE, "w")) == NULL){
      printf ("Unable to open %s\n", OUTPUT_FILE);
      exit (1);
  }
  fprintf (tf, "#ifndef __crc32cr_table_h__\n");
  fprintf (tf, "#define __crc32cr_table_h__\n\n");
  fprintf (tf, "#define CRC32C_POLY 0x%08lX\n", CRC32C_POLY);
  fprintf (tf, "#define CRC32C(c,d) (c=(c>>8)^crc_c[(c^(d))&0xFF])\n");
  fprintf (tf, "\nunsigned long  crc_c[256] =\n{\n");
  for (i = 0; i < 256; i++){
      fprintf (tf, "0x%08lXL, ", build_crc_table (i));
      if ((i & 3) == 3)
        
        fprintf (tf, "\n");
  }
   fprintf (tf, "};\n\n#endif\n");
        
        fprintf (tf, "\n");
  }
   fprintf (tf, "};\n\n#endif\n");
        
  if (fclose (tf) != 0)
    printf ("Unable to close <%s>." OUTPUT_FILE);
  else
    printf ("\nThe CRC-32c table has been written to <%s>.\n",
      OUTPUT_FILE);
}
        
  if (fclose (tf) != 0)
    printf ("Unable to close <%s>." OUTPUT_FILE);
  else
    printf ("\nThe CRC-32c table has been written to <%s>.\n",
      OUTPUT_FILE);
}
        
/* Example of crc insertion */
        
/* Example of crc insertion */
        

#include "crc32cr.h"

#包括“crc32cr.h”

unsigned long
generate_crc32c(unsigned char *buffer, unsigned int length)
{
  unsigned int i;
  unsigned long crc32 = ~0L;
  unsigned long result;
  unsigned char byte0,byte1,byte2,byte3;
        
unsigned long
generate_crc32c(unsigned char *buffer, unsigned int length)
{
  unsigned int i;
  unsigned long crc32 = ~0L;
  unsigned long result;
  unsigned char byte0,byte1,byte2,byte3;
        
  for (i = 0; i < length; i++){
      CRC32C(crc32, buffer[i]);
  }
  result = ~crc32;
        
  for (i = 0; i < length; i++){
      CRC32C(crc32, buffer[i]);
  }
  result = ~crc32;
        
  /*  result  now holds the negated polynomial remainder;
   *  since the table and algorithm is "reflected" [williams95].
   *  That is,  result has the same value as if we mapped the message
   *  to a polynomial, computed the host-bit-order polynomial
   *  remainder, performed final negation, then did an end-for-end
   *  bit-reversal.
   *  Note that a 32-bit bit-reversal is identical to four inplace
   *  8-bit reversals followed by an end-for-end byteswap.
   *  In other words, the bytes of each bit are in the right order,
   *  but the bytes have been byteswapped.  So we now do an explicit
   *  byteswap.  On a little-endian machine, this byteswap and
   *  the final ntohl cancel out and could be elided.
   */
        
  /*  result  now holds the negated polynomial remainder;
   *  since the table and algorithm is "reflected" [williams95].
   *  That is,  result has the same value as if we mapped the message
   *  to a polynomial, computed the host-bit-order polynomial
   *  remainder, performed final negation, then did an end-for-end
   *  bit-reversal.
   *  Note that a 32-bit bit-reversal is identical to four inplace
   *  8-bit reversals followed by an end-for-end byteswap.
   *  In other words, the bytes of each bit are in the right order,
   *  but the bytes have been byteswapped.  So we now do an explicit
   *  byteswap.  On a little-endian machine, this byteswap and
   *  the final ntohl cancel out and could be elided.
   */
        
  byte0 = result & 0xff;
  byte1 = (result>>8) & 0xff;
  byte2 = (result>>16) & 0xff;
  byte3 = (result>>24) & 0xff;
        
  byte0 = result & 0xff;
  byte1 = (result>>8) & 0xff;
  byte2 = (result>>16) & 0xff;
  byte3 = (result>>24) & 0xff;
        
  crc32 = ((byte0 << 24) |
           (byte1 << 16) |
           (byte2 << 8)  |
           byte3);
  return ( crc32 );
}
        
  crc32 = ((byte0 << 24) |
           (byte1 << 16) |
           (byte2 << 8)  |
           byte3);
  return ( crc32 );
}
        
int
insert_crc32(unsigned char *buffer, unsigned int length)
{
  SCTP_message *message;
  unsigned long crc32;
  message = (SCTP_message *) buffer;
  message->common_header.checksum = 0L;
  crc32 = generate_crc32c(buffer,length);
  /* and insert it into the message */
  message->common_header.checksum = htonl(crc32);
  return 1;
}
        
int
insert_crc32(unsigned char *buffer, unsigned int length)
{
  SCTP_message *message;
  unsigned long crc32;
  message = (SCTP_message *) buffer;
  message->common_header.checksum = 0L;
  crc32 = generate_crc32c(buffer,length);
  /* and insert it into the message */
  message->common_header.checksum = htonl(crc32);
  return 1;
}
        
int
validate_crc32(unsigned char *buffer, unsigned int length)
{
  SCTP_message *message;
  unsigned int i;
  unsigned long original_crc32;
  unsigned long crc32 = ~0L;
        
int
validate_crc32(unsigned char *buffer, unsigned int length)
{
  SCTP_message *message;
  unsigned int i;
  unsigned long original_crc32;
  unsigned long crc32 = ~0L;
        
  /* save and zero checksum */
  message = (SCTP_message *) buffer;
  original_crc32 = ntohl(message->common_header.checksum);
  message->common_header.checksum = 0L;
  crc32 = generate_crc32c(buffer,length);
  return ((original_crc32 == crc32)? 1 : -1);
}
        
  /* save and zero checksum */
  message = (SCTP_message *) buffer;
  original_crc32 = ntohl(message->common_header.checksum);
  message->common_header.checksum = 0L;
  crc32 = generate_crc32c(buffer,length);
  return ((original_crc32 == crc32)? 1 : -1);
}
        

Authors' Addresses

作者地址

Jonathan Stone Room 446, Mail code 9040 Gates building 4A Stanford, Ca 94305

乔纳森斯通446室,邮政编码9040盖茨大厦4A号斯坦福,加利福尼亚94305

   EMail: jonathan@dsg.stanford.edu
        
   EMail: jonathan@dsg.stanford.edu
        

Randall R. Stewart 24 Burning Bush Trail. Crystal Lake, IL 60012 USA

Randall R.Stewart 24号燃烧丛林小道。美国伊利诺伊州水晶湖60012

   EMail: rrs@cisco.com
        
   EMail: rrs@cisco.com
        

Douglas Otis 800 E. Middlefield Mountain View, CA 94043 USA

道格拉斯奥的斯800东米德尔菲尔德山景,加利福尼亚州94043美国

   EMail: dotis@sanlight.net
        
   EMail: dotis@sanlight.net
        

Full Copyright Statement

完整版权声明

Copyright (C) The Internet Society (2002). All Rights Reserved.

版权所有(C)互联网协会(2002年)。版权所有。

This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to the Internet Society or other Internet organizations, except as needed for the purpose of developing Internet standards in which case the procedures for copyrights defined in the Internet Standards process must be followed, or as required to translate it into languages other than English.

本文件及其译本可复制并提供给他人,对其进行评论或解释或协助其实施的衍生作品可全部或部分编制、复制、出版和分发,不受任何限制,前提是上述版权声明和本段包含在所有此类副本和衍生作品中。但是,不得以任何方式修改本文件本身,例如删除版权通知或对互联网协会或其他互联网组织的引用,除非出于制定互联网标准的需要,在这种情况下,必须遵循互联网标准过程中定义的版权程序,或根据需要将其翻译成英语以外的其他语言。

The limited permissions granted above are perpetual and will not be revoked by the Internet Society or its successors or assigns.

上述授予的有限许可是永久性的,互联网协会或其继承人或受让人不会撤销。

This document and the information contained herein is provided on an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

本文件和其中包含的信息是按“原样”提供的,互联网协会和互联网工程任务组否认所有明示或暗示的保证,包括但不限于任何保证,即使用本文中的信息不会侵犯任何权利,或对适销性或特定用途适用性的任何默示保证。

Acknowledgement

确认

Funding for the RFC Editor function is currently provided by the Internet Society.

RFC编辑功能的资金目前由互联网协会提供。