It is able to detect and correct multiple symbol errors. By adding t check symbols to the data, a Reed–Solomon code can detect any combination of up to t erroneous symbols, or correct up to ⌊t/2⌋ symbols. As an erasure code, it can correct up to t known erasures, or it can detect and correct combinations of errors and erasures. Reed–Solomon codes are also suitable as multiple-burst bit-error correcting codes, since a sequence of b + 1 consecutive bit errors can affect at most two symbols of size b. The choice of t is up to the designer of the code, and may be selected within wide limits.

Reed–Solomon codes were developed in 1960 by Irving S. Reed and Gustave Solomon, who were then staff members of MIT Lincoln Laboratory. Their seminal article was titled "Polynomial Codes over Certain Finite Fields." (Reed & Solomon 1960). The original encoding scheme described in the Reed & Solomon article used a variable polynomial based on the message to be encoded where only a fixed set of values (evaluation points) to be encoded are known to encoder and decoder. The original theoretical decoder generated potential polynomials based on subsets of k (unencoded message length) out of n (encoded message length) values of a received message, choosing the most popular polynomial as the correct one, which was impractical for all but the simplest of cases. This was initially resolved by changing the original scheme to a BCH code like scheme based on a fixed polynomial known to both encoder and decoder, but later, practical decoders based on the original scheme were developed, although slower than the BCH schemes. The result of this is that there are two main types of Reed Solomon codes, ones that use the original encoding scheme, and ones that use the BCH encoding scheme.

Also in 1960, a practical fixed polynomial decoder for BCH codes codes developed by Daniel Gorenstein and Neal Zierler was described in an MIT Lincoln Laboratory report by Zierler in January 1960 and later in a paper in June 1961.[2] The Gorenstein-Zierler decoder and the related work on BCH codes are described in a book Error Correcting Codes by W. Wesley Peterson (1961).[3] By 1963 (or possibly earlier), J. J. Stone (and others) recognized that Reed Solomon codes could use the BCH scheme of using a fixed generator polynomial, making such codes a special class of BCH codes,[4], but Reed Solomon codes based on the original encoding scheme, are not a class of BCH codes, and depending on the set of evaluation points, they are not even cyclic codes.

In 1996, variations of original scheme decoders called list decoders or soft decoders were developed by Madhu Sudan and others, and work continues on these type of decoders Guruswami–Sudan_list_decoding_algorithm .

In 2002, another original scheme decoder was developed by Shuhong Gao, based on the extended Euclid algorithm Gao_RS.pdf .

Reed–Solomon coding is very widely used in mass storage systems to correct the burst errors associated with media defects.

Reed–Solomon coding is a key component of the compact disc. It was the first use of strong error correction coding in a mass-produced consumer product, and DAT and DVD use similar schemes. In the CD, two layers of Reed–Solomon coding separated by a 28-way convolutionalinterleaver yields a scheme called Cross-Interleaved Reed–Solomon Coding (CIRC). The first element of a CIRC decoder is a relatively weak inner (32,28) Reed–Solomon code, shortened from a (255,251) code with 8-bit symbols. This code can correct up to 2 byte errors per 32-byte block. More importantly, it flags as erasures any uncorrectable blocks, i.e., blocks with more than 2 byte errors. The decoded 28-byte blocks, with erasure indications, are then spread by the deinterleaver to different blocks of the (28,24) outer code. Thanks to the deinterleaving, an erased 28-byte block from the inner code becomes a single erased byte in each of 28 outer code blocks. The outer code easily corrects this, since it can handle up to 4 such erasures per block.

The result is a CIRC that can completely correct error bursts up to 4000 bits, or about 2.5 mm on the disc surface. This code is so strong that most CD playback errors are almost certainly caused by tracking errors that cause the laser to jump track, not by uncorrectable error bursts.[6]

DVDs use a similar scheme, but with much larger blocks, a (208,192) inner code, and a (182,172) outer code.

Reed–Solomon error correction is also used in parchive files which are commonly posted accompanying multimedia files on USENET. The Distributed online storage service Wuala (discontinued in 2015) also used to make use of Reed–Solomon when breaking up files.

Almost all two-dimensional bar codes such as PDF-417, MaxiCode, Datamatrix, QR Code, and Aztec Code use Reed–Solomon error correction to allow correct reading even if a portion of the bar code is damaged. When the bar code scanner cannot recognize a bar code symbol, it will treat it as an erasure.

Reed–Solomon coding is less common in one-dimensional bar codes, but is used by the PostBar symbology.

Specialized forms of Reed–Solomon codes, specifically Cauchy-RS and Vandermonde-RS, can be used to overcome the unreliable nature of data transmission over erasure channels. The encoding process assumes a code of RS(N, K) which results in N codewords of length N symbols each storing K symbols of data, being generated, that are then sent over an erasure channel.

Any combination of K codewords received at the other end is enough to reconstruct all of the N codewords. The code rate is generally set to 1/2 unless the channel's erasure likelihood can be adequately modelled and is seen to be less. In conclusion, N is usually 2K, meaning that at least half of all the codewords sent must be received in order to reconstruct all of the codewords sent.

One significant application of Reed–Solomon coding was to encode the digital pictures sent back by the Voyager space probe.

Voyager introduced Reed–Solomon coding concatenated with convolutional codes, a practice that has since become very widespread in deep space and satellite (e.g., direct digital broadcasting) communications.

Viterbi decoders tend to produce errors in short bursts. Correcting these burst errors is a job best done by short or simplified Reed–Solomon codes.

The Reed–Solomon code is actually a family of codes, where every code is characterised by three parameters: an alphabet size q, a block lengthn, and a message lengthk, with k < n ≤ q. The set of alphabet symbols is interpreted as the finite field of order q, and thus, q has to be a prime power. In the most useful parameterizations of the Reed–Solomon code, the block length is usually some constant multiple of the message length, that is, the rateR = k/n is some constant, and furthermore, the block length is equal to or one less than the alphabet size, that is, n = q or n = q − 1.[citation needed]

Reed & Solomon's original view: The codeword as a sequence of values[edit]

There are different encoding procedures for the Reed–Solomon code, and thus, there are different ways to describe the set of all codewords. In the original view of Reed & Solomon (1960), every codeword of the Reed–Solomon code is a sequence of function values of a polynomial of degree less than k. In order to obtain a codeword of the Reed–Solomon code, the message is interpreted as the description of a polynomial p of degree less than k over the finite field F with q elements. In turn, the polynomial p is evaluated at n ≤ q distinct points a1,…,an{\displaystyle a_{1},\dots ,a_{n}} of the field F, and the sequence of values is the corresponding codeword. Common choices for a set of evaluation points include {0, 1, 2, ..., n-1}, {0, 1, α, α2, ..., αn-2 }, {0,α, α2, ..., αn-1 }, ... , where α is a primitive element of F.

Formally, the set C{\displaystyle \mathbf {C} } of codewords of the Reed–Solomon code is defined as follows:

C={(p(a1),p(a2),…,p(an))|p is a polynomial over F of degree <k}.{\displaystyle \mathbf {C} ={\Big \{}\;{\big (}p(a_{1}),p(a_{2}),\dots ,p(a_{n}){\big )}\;{\Big |}\;p{\text{ is a polynomial over }}F{\text{ of degree }}<k\;{\Big \}}\,.}

Since any two distinct polynomials of degree less than k{\displaystyle k} agree in at most k−1{\displaystyle k-1} points, this means that any two codewords of the Reed–Solomon code disagree in at least n−(k−1)=n−k+1{\displaystyle n-(k-1)=n-k+1} positions. Furthermore, there are two polynomials that do agree in k−2{\displaystyle k-2} points but are not equal, and thus, the distance of the Reed–Solomon code is exactly d=n−k+1{\displaystyle d=n-k+1}. Then the relative distance is δ=d/n=1−k/n+1/n=1−R+1/n∼1−R{\displaystyle \delta =d/n=1-k/n+1/n=1-R+1/n\sim 1-R}, where R=k/n{\displaystyle R=k/n} is the rate. This trade-off between the relative distance and the rate is asymptotically optimal since, by the Singleton bound, every code satisfies δ+R≤1+1/n{\displaystyle \delta +R\leq 1+1/n}. Being a code that achieves this optimal trade-off, the Reed–Solomon code belongs to the class of maximum distance separable codes.

While the number of different polynomials of degree less than k and the number of different messages are both equal to qk{\displaystyle q^{k}}, and thus every message can be uniquely mapped to such a polynomial, there are different ways of doing this encoding. The original construction of Reed & Solomon (1960) interprets the message x as the coefficients of the polynomial p, whereas subsequent constructions interpret the message as the values of the polynomial at the first k points a1,…,ak{\displaystyle a_{1},\dots ,a_{k}} and obtain the polynomial p by interpolating these values with a polynomial of degree less than k. The latter encoding procedure, while being slightly less efficient, has the advantage that it gives rise to a systematic code, that is, the original message is always contained as a subsequence of the codeword.

Simple encoding procedure: The message as a sequence of coefficients[edit]

In the original construction of Reed & Solomon (1960), the message x=(x1,…,xk)∈Fk{\displaystyle x=(x_{1},\dots ,x_{k})\in F^{k}} is mapped to the polynomial px{\displaystyle p_{x}} with

The codeword of x{\displaystyle x} is obtained by evaluating px{\displaystyle p_{x}} at n{\displaystyle n} different points a1,…,an{\displaystyle a_{1},\dots ,a_{n}} of the field F{\displaystyle F}. Thus the classical encoding function C:Fk→Fn{\displaystyle C:F^{k}\to F^{n}} for the Reed–Solomon code is defined as follows:

This function C{\displaystyle C} is a linear mapping, that is, it satisfies C(x)=x⋅A{\displaystyle C(x)=x\cdot A} for the following (k×n){\displaystyle (k\times n)}-matrix A{\displaystyle A} with elements from F{\displaystyle F}:

Systematic encoding procedure: The message as an initial sequence of values[edit]

There is an alternative encoding procedure that also produces the Reed–Solomon code, but that does so in a systematic way. Here, the mapping from the message x{\displaystyle x} to the polynomial px{\displaystyle p_{x}} works differently: the polynomial px{\displaystyle p_{x}} is now defined as the unique polynomial of degree less than k{\displaystyle k} such that

To compute this polynomial px{\displaystyle p_{x}} from x{\displaystyle x}, one can use Lagrange interpolation. Once it has been found, it is evaluated at the other points ak+1,…,an{\displaystyle a_{k+1},\dots ,a_{n}} of the field. The alternative encoding function C:Fk→Fn{\displaystyle C:F^{k}\to F^{n}} for the Reed–Solomon code is then again just the sequence of values:

Since the first k{\displaystyle k} entries of each codeword C(x){\displaystyle C(x)} coincide with x{\displaystyle x}, this encoding procedure is indeed systematic. Since Lagrange interpolation is a linear transformation, C{\displaystyle C} is a linear mapping. In fact, we have C(x)=x⋅G{\displaystyle C(x)=x\cdot G}, where

The inverse Fourier transform could be used to convert an error free set of n message values back into the encoding polynomial of k coefficients, with the constraint that in order for this to work, the set of evaluation points used to encode the message must be a set of increasing powers of α :

However, Lagrange interpolation performs the same conversion without the constraint on the set of evaluation points or the requirement of an error free set of message values and is used for systematic encoding, and in one of the steps of the Gao decoder.

In this view, the sender again maps the message x{\displaystyle x} to a polynomial px{\displaystyle p_{x}}, and for this, any of the two mappings just described can be used (where the message is either interpreted as the coefficients of px{\displaystyle p_{x}} or as the initial sequence of values of px{\displaystyle p_{x}}). Once the sender has constructed the polynomial px{\displaystyle p_{x}} in some way, however, instead of sending the values of px{\displaystyle p_{x}} at all points, the sender computes some related polynomial s{\displaystyle s} of degree at most n−1{\displaystyle n-1} for n=q−1{\displaystyle n=q-1} and sends the n{\displaystyle n}coefficients of that polynomial. The polynomial s(a){\displaystyle s(a)} is constructed by multiplying the message polynomial px(a){\displaystyle p_{x}(a)}, which has degree at most k−1{\displaystyle k-1}, with a generator polynomialg(a){\displaystyle g(a)} of degree n−k{\displaystyle n-k} that is known to both the sender and the receiver. The generator polynomial g(x){\displaystyle g(x)} is defined as the polynomial whose roots are exactly α,α2,…,αn−k{\displaystyle \alpha ,\alpha ^{2},\dots ,\alpha ^{n-k}}, i.e.,

The transmitter sends the n=q−1{\displaystyle n=q-1} coefficients of s(a)=px(a)⋅g(a){\displaystyle s(a)=p_{x}(a)\cdot g(a)}. Thus, in the BCH view of Reed–Solomon codes, the set C{\displaystyle \mathbf {C} } of codewords is defined for n=q−1{\displaystyle n=q-1} as follows:[7]

C={(s1,s2,…,sn)|s(a)=∑i=1nsiai−1 is a polynomial that has at least the roots α1,α2,…,αn−k}.{\displaystyle \mathbf {C} =\left\{\left(s_{1},s_{2},\dots ,s_{n}\right)\;{\Big |}\;s(a)=\sum _{i=1}^{n}s_{i}a^{i-1}{\text{ is a polynomial that has at least the roots }}\alpha ^{1},\alpha ^{2},\dots ,\alpha ^{n-k}\right\}\,.}

The encoding procedure for the BCH view of Reed–Solomon codes can be modified to yield a systematic encoding procedure, in which each codeword contains the message as a prefix. Here, instead of sending s(x)=p(x)g(x){\displaystyle s(x)=p(x)g(x)}, the encoder constructs the transmitted polynomial s(x){\displaystyle s(x)} such that the coefficients of the k{\displaystyle k} largest monomials are equal to the corresponding coefficients of p(x){\displaystyle p(x)}, and the lower-order coefficients of s(x){\displaystyle s(x)} are chosen exactly in such a way that s(x){\displaystyle s(x)} becomes divisible by g(x){\displaystyle g(x)}. Then the coefficients of p(x){\displaystyle p(x)} are a subsequence of the coefficients of s(x){\displaystyle s(x)}. To get a code that is overall systematic, we construct the message polynomial p(x){\displaystyle p(x)} by interpreting the message as the sequence of its coefficients.

Formally, the construction is done by multiplying p(x){\displaystyle p(x)} by xt{\displaystyle x^{t}} to make room for the t=n−k{\displaystyle t=n-k} check symbols, dividing that product by g(x){\displaystyle g(x)} to find the remainder, and then compensating for that remainder by subtracting it. The t{\displaystyle t} check symbols are created by computing the remainder sr(x){\displaystyle s_{r}(x)}:

Note that the remainder has degree at most t−1{\displaystyle t-1}, whereas the coefficients of xt−1,xt−2,…,x1,x0{\displaystyle x^{t-1},x^{t-2},\dots ,x^{1},x^{0}} in the polynomial p(x)⋅xt{\displaystyle p(x)\cdot x^{t}} are zero. Therefore, the following definition of the codeword s(x){\displaystyle s(x)} has the property that the first k{\displaystyle k} coefficients are identical to the coefficients of p(x){\displaystyle p(x)}:

s(x)=p(x)⋅xt−sr(x).{\displaystyle s(x)=p(x)\cdot x^{t}-s_{r}(x)\,.}

As a result, the codewords s(x){\displaystyle s(x)} are indeed elements of C{\displaystyle \mathbf {C} }, that is, they are divisible by the generator polynomial g(x){\displaystyle g(x)}:[8]

The error-correcting ability of a Reed–Solomon code is determined by its minimum distance, or equivalently, by n−k{\displaystyle n-k}, the measure of redundancy in the block. If the locations of the error symbols are not known in advance, then a Reed–Solomon code can correct up to (n−k)/2{\displaystyle (n-k)/2} erroneous symbols, i.e., it can correct half as many errors as there are redundant symbols added to the block. Sometimes error locations are known in advance (e.g., "side information" in demodulatorsignal-to-noise ratios)—these are called erasures. A Reed–Solomon code (like any MDS code) is able to correct twice as many erasures as errors, and any combination of errors and erasures can be corrected as long as the relation 2E + S ≤ n − k is satisfied, where E{\displaystyle E} is the number of errors and S{\displaystyle S} is the number of erasures in the block.

For practical uses of Reed–Solomon codes, it is common to use a finite field F{\displaystyle F} with 2m{\displaystyle 2^{m}} elements. In this case, each symbol can be represented as an m{\displaystyle m}-bit value. The sender sends the data points as encoded blocks, and the number of symbols in the encoded block is n=2m−1{\displaystyle n=2^{m}-1}. Thus a Reed–Solomon code operating on 8-bit symbols has n=28−1=255{\displaystyle n=2^{8}-1=255} symbols per block. (This is a very popular value because of the prevalence of byte-oriented computer systems.) The number k{\displaystyle k}, with k<n{\displaystyle k<n}, of data symbols in the block is a design parameter. A commonly used code encodes k=223{\displaystyle k=223} eight-bit data symbols plus 32 eight-bit parity symbols in an n=255{\displaystyle n=255}-symbol block; this is denoted as a (n,k)=(255,223){\displaystyle (n,k)=(255,223)} code, and is capable of correcting up to 16 symbol errors per block.

The Reed–Solomon code properties discussed above make them especially well-suited to applications where errors occur in bursts. This is because it does not matter to the code how many bits in a symbol are in error — if multiple bits in a symbol are corrupted it only counts as a single error. Conversely, if a data stream is not characterized by error bursts or drop-outs but by random single bit errors, a Reed–Solomon code is usually a poor choice compared to a binary code.

The Reed–Solomon code, like the convolutional code, is a transparent code. This means that if the channel symbols have been inverted somewhere along the line, the decoders will still operate. The result will be the inversion of the original data. However, the Reed–Solomon code loses its transparency when the code is shortened. The "missing" bits in a shortened code need to be filled by either zeros or ones, depending on whether the data is complemented or not. (To put it another way, if the symbols are inverted, then the zero-fill needs to be inverted to a one-fill.) For this reason it is mandatory that the sense of the data (i.e., true or complemented) be resolved before Reed–Solomon decoding.

Whether the Reed–Solomon code is cyclic or not depends on subtle details of the construction. In the original view of Reed and Solomon, where the codewords are the values of a polynomial, one can choose the sequence of evaluation points in such a way as to make the code cyclic. In particular, if α{\displaystyle \alpha } is a primitive root of the field F{\displaystyle F}, then by definition all non-zero elements of F{\displaystyle F} take the form αi{\displaystyle \alpha ^{i}} for i∈{1,…,q−1}{\displaystyle i\in \{1,\dots ,q-1\}}, where q=|F|{\displaystyle q=|F|}. Each polynomial p{\displaystyle p} over F{\displaystyle F} gives rise to a codeword (p(α1),…,p(αq−1)){\displaystyle (p(\alpha ^{1}),\dots ,p(\alpha ^{q-1}))}. Since the function a↦p(αa){\displaystyle a\mapsto p(\alpha a)} is also a polynomial of the same degree, this function gives rise to a codeword (p(α2),…,p(αq)){\displaystyle (p(\alpha ^{2}),\dots ,p(\alpha ^{q}))}; since αq=α1{\displaystyle \alpha ^{q}=\alpha ^{1}} holds, this codeword is the cyclic left-shift of the original codeword derived from p{\displaystyle p}. So choosing a sequence of primitive root powers as the evaluation points makes the original view Reed–Solomon code cyclic. Reed–Solomon codes in the BCH view are always cyclic because BCH codes are cyclic.

Designers are not required to use the "natural" sizes of Reed–Solomon code blocks. A technique known as "shortening" can produce a smaller code of any desired size from a larger code. For example, the widely used (255,223) code can be converted to a (160,128) code by padding the unused portion of the source block with 95 binary zeroes and not transmitting them. At the decoder, the same portion of the block is loaded locally with binary zeroes. The Delsarte-Goethals-Seidel[9] theorem illustrates an example of an application of shortened Reed–Solomon codes. In parallel to shortening, a technique known as puncturing allows omitting some of the encoded parity symbols.

The decoders described in this section use the Reed Solomon original view of a codeword as a sequence of polynomial values where the polynomial is based on the message to be encoded. The same set of fixed values are used by the encoder and decoder, and the decoder recovers the encoding polynomial (and optionally an error locating polynomial) from the received message.

Reed & Solomon (1960) described a theoretical decoder that corrected errors by finding the most popular message polynomial. The decoder only knows the set of values a1{\displaystyle a_{1}} to an{\displaystyle a_{n}} and which encoding method was used to generate the codeword's sequence of values. The original message, the polynomial, and any errors are unknown. A decoding procedure could use a method like Lagrange interpolation on various subsets of n codeword values taken k at a time to repeatedly produce potential polynomials, until a sufficient number of matching polynomials are produced to reasonably eliminate any errors in the received codeword. Once a polynomial is determined, then any errors in the codeword can be corrected, by recalculating the corresponding codeword values. Unfortunately, in all but the simplest of cases, there are too many subsets, so the algorithm is impractical. The number of subsets is the binomial coefficient, (nk)=n!(n−k)!k!{\displaystyle \textstyle {\binom {n}{k}}={n! \over (n-k)!k!}}, and the number of subsets is infeasible for even modest codes. For a (255,249){\displaystyle (255,249)} code that can correct 3 errors, the naive theoretical decoder would examine 359 billion subsets.

In 1986, a decoder known as the Berlekamp–Welch algorithm was developed as a decoder that is able to recover the original message polynomial as well as an error "locator" polynomial that produces zeroes for the input values that correspond to errors, with time complexity O(n^3), where n is the number of values in a message. The recovered polynomial is then used to recover (recalculate as needed) the original message.

Daniel Gorenstein and Neal Zierler developed a decoder that was described in a MIT Lincoln Laboratory report by Zierler in January 1960 and later in a paper in June 1961.[10] The Gorenstein-Zierler decoder and the related work on BCH codes are described in a book Error Correcting Codes by W. Wesley Peterson (1961).[11]

The transmitted polynomial is corrupted in transit by an error polynomial e(x) to produce the received polynomial r(x).

r(x)=s(x)+e(x){\displaystyle r(x)=s(x)+e(x)}

e(x)=∑i=0n−1eixi{\displaystyle e(x)=\sum _{i=0}^{n-1}e_{i}x^{i}}

where ei is the coefficient for the i-th power of x. Coefficient ei will be zero if there is no error at that power of x and nonzero if there is an error. If there are ν errors at distinct powers ik of x, then

The goal of the decoder is to find the number of errors (ν), the positions of the errors (ik), and the error values at those positions (eik). From those, e(x) can be calculated and subtracted from r(x) to get the original message s(x).

Then the syndromes can be written in terms of the error locators and error values as

Sj=∑k=1νYkXkj{\displaystyle S_{j}=\sum _{k=1}^{\nu }Y_{k}X_{k}^{j}}

The syndromes give a system of n − k ≥ 2ν equations in 2ν unknowns, but that system of equations is nonlinear in the Xk and does not have an obvious solution. However, if the Xk were known (see below), then the syndrome equations provide a linear system of equations that can easily be solved for the Yk error values.

The above assumes the decoder knows the number of errors ν, but that number has not been determined yet. The PGZ decoder does not determine ν directly but rather searches for it by trying successive values. The decoder first assumes the largest value for a trial ν and sets up the linear system for that value. If the equations can be solved (i.e., the matrix determinant is nonzero), then that trial value is the number of errors. If the linear system cannot be solved, then the trial ν is reduced by one and the next smaller system is examined. (Gill n.d., p. 35)

Use the coefficients Λi found in the last step to build the error location polynomial. The roots of the error location polynomial can be found by exhaustive search. The error locators are the reciprocals of those roots. Note that the order of coefficients of the error location polynomial can be reversed, in which case the roots of that polynomial are the error locators (not reciprocals). Chien search is an efficient implementation of this step.

The Berlekamp–Massey algorithm is an alternate iterative procedure for finding the error locator polynomial. During each iteration, it calculates a discrepancy based on a current instance of Λ(x) with an assumed number of errors e:

and then adjusts Λ(x) and e so that a recalculated Δ would be zero. The article Berlekamp–Massey algorithm has a detailed description of the procedure. In the following example, C(x) is used to represent Λ(x).

A discrete Fourier transform can be used for decoding.[12] To avoid conflict with syndrome names, let c(x) = s(x) the encoded codeword. r(x) and e(x) are the same as above. Define C(x), E(x), and R(x) as the discrete Fourier transforms of c(x), e(x), and r(x). Since r(x) = c(x) + e(x), and since a discrete Fourier transform is a linear operator, R(x) = C(x) + E(x).

Transform r(x) to R(x) using discrete Fourier transform. Since the calculation for a discrete Fourier transform is the same as the calculation for syndromes, t coefficients of R(x) and E(x) are the same as the syndromes:

Rj=Ej=Sj=r(αj){\displaystyle R_{j}=E_{j}=S_{j}=r(\alpha ^{j})}

for1≤j≤t{\displaystyle for\ 1\leq j\leq t}

Use R1{\displaystyle R_{1}} through Rt{\displaystyle R_{t}} as syndromes (they're the same) and generate the error locator polynomial using the methods from any of the above decoders.

Let v = number of errors. Generate E(x) using the known coefficients E1{\displaystyle E_{1}} to Et{\displaystyle E_{t}}, the error locator polynomial, and these formulas

The Singleton bound states that the minimum distance d of a linear block code of size (n,k) is upper-bounded by n − k + 1. The distance d was usually understood to limit the error-correction capability to ⌊d/2⌋. The Reed–Solomon code achieves this bound with equality, and can thus correct up to ⌊(n − k + 1)/2⌋ errors. However, this error-correction bound is not exact.

In 1999, Madhu Sudan and Venkatesan Guruswami at MIT published "Improved Decoding of Reed–Solomon and Algebraic-Geometry Codes" introducing an algorithm that allowed for the correction of errors beyond half the minimum distance of the code.[13] It applies to Reed–Solomon codes and more generally to algebraic geometric codes. This algorithm produces a list of codewords (it is a list-decoding algorithm) and is based on interpolation and factorization of polynomials over GF(2m){\displaystyle GF(2^{m})} and its extensions.

The algebraic decoding methods described above are hard-decision methods, which means that for every symbol a hard decision is made about its value. For example, a decoder could associate with each symbol an additional value corresponding to the channel demodulator's confidence in the correctness of the symbol. The advent of LDPC and turbo codes, which employ iterated soft-decision belief propagation decoding methods to achieve error-correction performance close to the theoretical limit, has spurred interest in applying soft-decision decoding to conventional algebraic codes. In 2003, Ralf Koetter and Alexander Vardy presented a polynomial-time soft-decision algebraic list-decoding algorithm for Reed–Solomon codes, which was based upon the work by Sudan and Guruswami.[14] In 2016, Steven J. Franke and Joseph H. Taylor published a novel soft-decision decoder.[15]

function[ encoded ] =rsEncoder( msg, m, prim_poly, n, k )%RSENCODER Encode message with the Reed-Solomon algorithm% m is the number of bits per symbol% prim_poly: Primitive polynomial p(x). Ie for DM is 301% k is the size of the message% n is the total size (k+redundant)% Example: msg = uint8('Test')% enc_msg = rsEncoder(msg, 8, 301, 12, numel(msg));% Get the alphaalpha=gf(2,m,prim_poly);% Get the Reed-Solomon generating polynomial g(x)g_x=genpoly(k,n,alpha);% Multiply the information by X^(n-k), or just pad with zeros at the end to% get space to add the redundant informationmsg_padded=gf([msgzeros(1,n-k)],m,prim_poly);% Get the remainder of the division of the extended message by the % Reed-Solomon generating polynomial g(x)[~,reminder]=deconv(msg_padded,g_x);% Now return the message with the redundant informationencoded=msg_padded-reminder;end% Find the Reed-Solomon generating polynomial g(x), by the way this is the% same as the rsgenpoly function on matlabfunctiong =genpoly(k, n, alpha)g=1;% A multiplication on the galois field is just a convolutionfork=mod(1:n-k,n)g=conv(g,[1alpha.^(k)]);endend

function[ decoded, error_pos, error_mag, g, S ] =rsDecoder( encoded, m, prim_poly, n, k )%RSDECODER Decode a Reed-Solomon encoded message% Example:% [dec, ~, ~, ~, ~] = rsDecoder(enc_msg, 8, 301, 12, numel(msg))max_errors=floor((n-k)/2);orig_vals=encoded.x;% Initialize the error vectorerrors=zeros(1,n);g=[];S=[];% Get the alphaalpha=gf(2,m,prim_poly);% Find the syndromes (Check if dividing the message by the generator% polynomial the result is zero)Synd=polyval(encoded,alpha.^(1:n-k));Syndromes=trim(Synd);% If all syndromes are zeros (perfectly divisible) there are no errorsifisempty(Syndromes.x)decoded=orig_vals(1:k);error_pos=[];error_mag=[];g=[];S=Synd;return;end% Prepare for the euclidean algorithm (Used to find the error locating% polynomials)r0=[1,zeros(1,2*max_errors)];r0=gf(r0,m,prim_poly);r0=trim(r0);size_r0=length(r0);r1=Syndromes;f0=gf([zeros(1,size_r0-1)1],m,prim_poly);f1=gf(zeros(1,size_r0),m,prim_poly);g0=f1;g1=f0;% Do the euclidean algorithm on the polynomials r0(x) and Syndromes(x) in% order to find the error locating polynomialwhiletrue% Do a long division[quotient,remainder]=deconv(r0,r1);% Add some zerosquotient=pad(quotient,length(g1));% Find quotient*g1 and padc=conv(quotient,g1);c=trim(c);c=pad(c,length(g0));% Update g as g0-quotient*g1g=g0-c;% Check if the degree of remainder(x) is less than max_errorsifall(remainder(1:end-max_errors)==0)break;end% Update r0, r1, g0, g1 and remove leading zerosr0=trim(r1);r1=trim(remainder);g0=g1;g1=g;end% Remove leading zerosg=trim(g);% Find the zeros of the error polynomial on this galois fieldevalPoly=polyval(g,alpha.^(n-1:-1:0));error_pos=gf(find(evalPoly==0),m);% If no error position is found we return the received work, because% basically is nothing that we could do and we return the received messageifisempty(error_pos)decoded=orig_vals(1:k);error_mag=[];return;end% Prepare a linear system to solve the error polynomial and find the error% magnitudessize_error=length(error_pos);Syndrome_Vals=Syndromes.x;b(:,1)=Syndrome_Vals(1:size_error);foridx=1:size_errore=alpha.^(idx*(n-error_pos.x));err=e.x;er(idx,:)=err;end% Solve the linear systemerror_mag=(gf(er,m,prim_poly)\gf(b,m,prim_poly))';% Put the error magnitude on the error vectorerrors(error_pos.x)=error_mag.x;% Bring this vector to the galois fielderrors_gf=gf(errors,m,prim_poly);% Now to fix the errors just add with the encoded codedecoded_gf=encoded(1:k)+errors_gf(1:k);decoded=decoded_gf.x;end% Remove leading zeros from galois arrayfunctiongt =trim(g)gx=g.x;gt=gf(gx(find(gx,1):end),g.m,g.prim_poly);end% Add leading zerosfunctionxpad =pad(x,k)len=length(x);if(len<k)xpad=[zeros(1,k-len)x];endend