| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- //Copyright (c) 2019 by Jason Southwell
- //
- //Permission is hereby granted, free of charge, to any person obtaining a copy
- //of this software and associated documentation files (the "Software"), to deal
- //in the Software without restriction, including without limitation the rights
- //to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- //copies of the Software, and to permit persons to whom the Software is
- //furnished to do so, subject to the following conditions:
- //
- //The above copyright notice and this permission notice shall be included in all
- //copies or substantial portions of the Software.
- //
- //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- //AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- //LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- //SOFTWARE.
- unit qr.rs;
- interface
- uses System.SysUtils, System.Classes;
- type
- EReedSolomonException = exception;
- TReedSolomonGenerator = class(TObject)
- private
- FCoefficients : TArray<Byte>;
- public
- constructor Create(Degree : integer);
- function GetRemaineder(const Data : TArray<Byte>) : TArray<Byte>;
- function Multiply(x, y : Byte) : Byte;
- end;
- implementation
- { TReedSolomonGenerator }
- constructor TReedSolomonGenerator.Create(Degree: integer);
- var
- i, j : integer;
- root : Byte;
- begin
- if (Degree < 1) or (Degree > 255) then
- raise EReedSolomonException.Create('Degree out of range');
- inherited Create;
- SetLength(FCoefficients,Degree);
- for i := 0 to degree-2 do
- FCoefficients[i] := 0;
- FCoefficients[Degree-1] := 1;
- root := 1;
- for i := 0 to degree-1 do
- begin
- for j := 0 to Length(FCoefficients)-1 do
- begin
- FCoefficients[j] := Multiply(FCoefficients[j], root);
- if (j + 1 < length(FCoefficients)) then
- FCoefficients[j] := FCoefficients[j] xor FCoefficients[j + 1];
- end;
- root := Multiply(root, 2);
- end;
- end;
- function TReedSolomonGenerator.GetRemaineder(const Data: TArray<Byte>): TArray<Byte>;
- var
- i: Integer;
- ary : TArray<Byte>;
- b, factor : Byte;
- j: Integer;
- begin
- SetLength(Result, Length(FCoefficients));
- for i := 0 to Length(FCoefficients)-1 do
- Result[i] := 0;
- ary := Data;
- for i := 0 to Length(ary)-1 do
- begin
- b := ary[i];
- factor := b xor Result[0];
- Delete(Result,0,1);
- SetLength(Result, Length(Result)+1);
- Result[Length(Result)-1] := 0;
- for j := 0 to Length(FCoefficients)-1 do
- begin
- Result[j] := Result[j] xor Multiply(FCoefficients[j], factor);
- end;
- end;
- end;
- function TReedSolomonGenerator.Multiply(x, y : Byte): Byte;
- var
- i : integer;
- bResult : Byte;
- begin
- if (x shr 8 <> 0) or (y shr 8 <> 0) then
- raise EReedSolomonException.Create('Byte out of range.');
- bResult := 0;
- for i := 7 downto 0 do
- begin
- bResult := (bResult shl 1) xor ((bResult shr 7) * $11D);
- bResult := (bResult xor (((y shr i) and 1) * x));
- end;
- if bResult shr 8 <> 0 then
- raise EReedSolomonException.Create('Assertion Error');
- Result := bResult;
- end;
- end.
|