LRC 計算

回覆文章
yehlu
Site Admin
文章: 3245
註冊時間: 2004-04-15 17:20:21
來自: CodeCharge Support Engineer

LRC 計算

文章 yehlu »

http://www.blueshop.com.tw/board/FUM20 ... 2373.html

代碼: 選擇全部

public static byte calculateLRC(byte[] bytes)
{
    return bytes.Aggregate<byte, byte>(0, (x, y) => (byte) (x^ y));
}
yehlu
Site Admin
文章: 3245
註冊時間: 2004-04-15 17:20:21
來自: CodeCharge Support Engineer

Re: LRC 計算

文章 yehlu »

http://wushinetlife.blogspot.tw/2011/11 ... st_09.html

2011年11月9日 星期三
信用卡機

引用:
--

1.LRC是checksum用.應是針對(Data[]+ETX)作XOR的結果.

Data=Data[0];
for ( i=1; i < length; i++ ) Data = Data xor Data;
LRC=Data xor ETX;

2.在將 (header data if need)+ Data[]+ETX+LRC +(tail data if need) 送到前端設備.

CRC、Checksum、VRC、LRC之比較(1.使用bit數的多寡 2.作法上的使用 3.佔記憶空間 4.是否會誤判之排行榜)
CRC(循環冗餘檢查碼,Cyclic Redundancy Check),目前較常使用的位元數目有8、16或32,一般縮寫為CRC-8、CRC-16、CRC-32。根據理論統計,CRC-16可完全偵測資料區塊內單一或兩個位元的錯誤、奇數個位元的錯誤、連續16個位元或少於此數的錯誤,超過17個連續位元的錯誤偵測率則有99.9969%,其它位元長度的錯誤偵測率則可達99.9984%。XMODEM、Kermit等通訊協定,PC 的磁碟機、FDDI、乙太網路和「光纖通道」使用CRC驗證。
Checksum(總和檢查)使用的位元數沒有特別提到。Apple個人電腦的磁碟機是利用checksum驗證資料的正確性。
VRC(垂直冗餘檢查,Vertical Redundancy Check)是對每一個傳送字元(一般是8位元)都增加一個額外位元。
LRC(縱向冗餘檢查,Longitudinal Redundancy Check)也是對每一個傳送字元(一般是8位元)都增加一個額外位元。磁帶資料及透過通訊線路傳送的資料可用LRC驗證。
錯誤檢查所佔用的記憶體空間應與使用的位元數有正相關,誤判的機率應與使用的位元數有負相關,但是詳細的數字還是請您查看書籍與相關研究報告(不過對於VRC和LRC的討論及比較相當少)。


unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
private
Procedure ConnectPrint(var aHandle : THandle);//開始連結COM1
function GetTransData : String;
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
aHandle : THandle;
lrc : Longword;
s, s1 : string;
i : Integer;
bb : byte;
begin
//開啟COM1
ConnectPrint(aHandle);
//送出要求(144BYTE)
s := GetTransData;
s1 := s;
//取得lrc的值
for i := 0 to length(s) - 1 do
begin
bb := byte(s);
s1 := chr(bb xor 3);
end;
S := PCHAR(CHR($02) + S + CHR($03) + S1);
WriteFile(aHandle, S , 290, lrc, nil);
//關閉COM1
CloseHandle(aHandle);
end;

procedure TForm1.ConnectPrint(var aHandle : THandle);
var
Temp : String;
dcb : _DCB;
lrc : Longword;
begin
temp := 'COM1';
aHandle := CreateFile(PChar(temp),
GENERIC_READ OR GENERIC_WRITE,
0,
nil,
OPEN_EXISTING,
0,
0 );

end;

function TForm1.GetTransData: String;
var
aString : String;
begin
{Trans Type ( 2)
Host ID ( 2)
Invoice No ( 6)
Card No (19)
Card Exp Date ( 4)
Trans Amt (12)
Trans Date ( 6)
Trans Time ( 6)
Approval Code ( 9)
Amount 1 (12)
Resp Code ( 4)
Terminal Id ( 8)
Ref No (12)
Amount2 (12)
StoreID (16)
Reserved (13)
}
aString := '01'
+ '02'
+ '000000'
+ '0000000000000000000'
+ '0000'
+ '000000128000'
+ '000000' //6
+ '000000' //6
+ '000000000'//9
+ '000000000000'
+ '0000'
+ '00000000'
+ '00000000'
+ '000000000000'//12
+ '000000000000'//12
+ '00000000000000000'//17
+ '0000000000000';//13
Result := aString;
end;

end.
yehlu
Site Admin
文章: 3245
註冊時間: 2004-04-15 17:20:21
來自: CodeCharge Support Engineer

Re: LRC 計算

文章 yehlu »

https://github.com/alohasteveb/lrc-php

代碼: 選擇全部

<?php

namespace AlohaSteve;

/**
* Implementation of Longitudinal Redundancy Check.
*
* @author Steve Be
* @version 0.1.0
*
*/

class Lrc {
  private $endSymbol = NULL;

/**
* @param string $symbol A 1-byte or 1-character end symbol. Use a single-byte character set.
* @throws \LrcConfigurationException If parameter is not a single character/byte
*/
  public function setEndSymbol($symbol = NULL) {
    if (is_null($symbol) || (strlen($symbol) !== 1)) throw new LrcConfigurationException("End symbol must be exactly 1 byte long.");

    $this->endSymbol = $symbol;
  }


  /**
  * @param string $message A non-empty message for which to generate the check byte/character. Use a single-byte character set.
  * @throws \LrcConfigurationException If end symbol is not set or message is empty.
  */

  public function getCheck($message = NULL) {
    if (is_null($this->endSymbol)) throw new LrcConfigurationException("End Symbol must be set to generate a check.");
    if (is_null($message) || (strlen($message) === 0)) throw new LrcConfigurationException("Messages must be at least 1 byte long.");

    $extendedMessage = $message . $this->endSymbol;

    $extendedMessageLength = strlen($extendedMessage);

    $check = substr($extendedMessage, 0, 1);
    for ($i = 1; $i < $extendedMessageLength ; $i++) {
            $check ^= substr($extendedMessage, $i, 1);
    }
    return $check;
  }
}


class LrcException extends \Exception {};
class LrcConfigurationException extends LrcException {};
require('Lrc.class.php');

$myLrc = new \AlohaSteve\Lrc();

$myLrc->setEndSymbol($endSymbol);

$extendedMessage = $startSymbol . $baseMessage . $endSymbol . $myLrc->getCheck($baseMessage); //LRC calculation includes termination/ending symbol but not start symbol
回覆文章

回到「PHP」