qr.rs.pas 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. //Copyright (c) 2019 by Jason Southwell
  2. //
  3. //Permission is hereby granted, free of charge, to any person obtaining a copy
  4. //of this software and associated documentation files (the "Software"), to deal
  5. //in the Software without restriction, including without limitation the rights
  6. //to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. //copies of the Software, and to permit persons to whom the Software is
  8. //furnished to do so, subject to the following conditions:
  9. //
  10. //The above copyright notice and this permission notice shall be included in all
  11. //copies or substantial portions of the Software.
  12. //
  13. //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. //AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. //LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18. //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  19. //SOFTWARE.
  20. unit qr.rs;
  21. interface
  22. uses System.SysUtils, System.Classes;
  23. type
  24. EReedSolomonException = exception;
  25. TReedSolomonGenerator = class(TObject)
  26. private
  27. FCoefficients : TArray<Byte>;
  28. public
  29. constructor Create(Degree : integer);
  30. function GetRemaineder(const Data : TArray<Byte>) : TArray<Byte>;
  31. function Multiply(x, y : Byte) : Byte;
  32. end;
  33. implementation
  34. { TReedSolomonGenerator }
  35. constructor TReedSolomonGenerator.Create(Degree: integer);
  36. var
  37. i, j : integer;
  38. root : Byte;
  39. begin
  40. if (Degree < 1) or (Degree > 255) then
  41. raise EReedSolomonException.Create('Degree out of range');
  42. inherited Create;
  43. SetLength(FCoefficients,Degree);
  44. for i := 0 to degree-2 do
  45. FCoefficients[i] := 0;
  46. FCoefficients[Degree-1] := 1;
  47. root := 1;
  48. for i := 0 to degree-1 do
  49. begin
  50. for j := 0 to Length(FCoefficients)-1 do
  51. begin
  52. FCoefficients[j] := Multiply(FCoefficients[j], root);
  53. if (j + 1 < length(FCoefficients)) then
  54. FCoefficients[j] := FCoefficients[j] xor FCoefficients[j + 1];
  55. end;
  56. root := Multiply(root, 2);
  57. end;
  58. end;
  59. function TReedSolomonGenerator.GetRemaineder(const Data: TArray<Byte>): TArray<Byte>;
  60. var
  61. i: Integer;
  62. ary : TArray<Byte>;
  63. b, factor : Byte;
  64. j: Integer;
  65. begin
  66. SetLength(Result, Length(FCoefficients));
  67. for i := 0 to Length(FCoefficients)-1 do
  68. Result[i] := 0;
  69. ary := Data;
  70. for i := 0 to Length(ary)-1 do
  71. begin
  72. b := ary[i];
  73. factor := b xor Result[0];
  74. Delete(Result,0,1);
  75. SetLength(Result, Length(Result)+1);
  76. Result[Length(Result)-1] := 0;
  77. for j := 0 to Length(FCoefficients)-1 do
  78. begin
  79. Result[j] := Result[j] xor Multiply(FCoefficients[j], factor);
  80. end;
  81. end;
  82. end;
  83. function TReedSolomonGenerator.Multiply(x, y : Byte): Byte;
  84. var
  85. i : integer;
  86. bResult : Byte;
  87. begin
  88. if (x shr 8 <> 0) or (y shr 8 <> 0) then
  89. raise EReedSolomonException.Create('Byte out of range.');
  90. bResult := 0;
  91. for i := 7 downto 0 do
  92. begin
  93. bResult := (bResult shl 1) xor ((bResult shr 7) * $11D);
  94. bResult := (bResult xor (((y shr i) and 1) * x));
  95. end;
  96. if bResult shr 8 <> 0 then
  97. raise EReedSolomonException.Create('Assertion Error');
  98. Result := bResult;
  99. end;
  100. end.