Skip to content

Commit

Permalink
Release 2.0
Browse files Browse the repository at this point in the history
I really hope I don't have to change the API again.
  • Loading branch information
clausecker committed Aug 30, 2014
1 parent 9c9c28f commit bdcf5f9
Show file tree
Hide file tree
Showing 11 changed files with 2,217 additions and 8 deletions.
106 changes: 106 additions & 0 deletions 2.0/nfc/crc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
// Copyright (c) 2014, Robert Clausecker <[email protected]>
//
// This program is free software: you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published by the
// Free Software Foundation, version 3.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>

// The code in this file is a very direct translation of the code in
// iso14443-subr.c of the libnfc version 1.7.0 translated to Go for performance
// reasons.

package nfc

// Calculate an ISO 14443a CRC. Code translated from the code in
// iso14443a_crc().
func ISO14443aCRC(data []byte) [2]byte {
crc := uint32(0x6363)
for _, bt := range data {
bt ^= uint8(crc & 0xff)
bt ^= bt << 4
bt32 := uint32(bt)
crc = (crc >> 8) ^ (bt32 << 8) ^ (bt32 << 3) ^ (bt32 >> 4)
}

return [2]byte{byte(crc & 0xff), byte((crc >> 8) & 0xff)}
}

// Calculate an ISO 14443a CRC and append it to the supplied slice.
func AppendISO14443aCRC(data []byte) []byte {
crc := ISO14443aCRC(data)
return append(data, crc[0], crc[1])
}

// Calculate an ISO 14443b CRC. Code translated from the code in
// iso14443b_crc().
func ISO14443bCRC(data []byte) [2]byte {
crc := uint32(0xffff)
for _, bt := range data {
bt ^= uint8(crc & 0xff)
bt ^= bt << 4
bt32 := uint32(bt)
crc = (crc >> 8) ^ (bt32 << 8) ^ (bt32 << 3) ^ (bt32 >> 4)
}

return [2]byte{byte(crc & 0xff), byte((crc >> 8) & 0xff)}
}

// Calculate an ISO 14443b CRC and append it to the supplied slice.
func AppendISO14443bCRC(data []byte) []byte {
crc := ISO14443bCRC(data)
return append(data, crc[0], crc[1])
}

// Locate historical bytes according to ISO/IEC 14443-4 sec. 5.2.7. Return nil
// if that fails.
func ISO14443aLocateHistoricalBytes(ats []byte) []byte {
if len(ats) > 0 {
offset := 1
if ats[0]&0x10 != 0 {
offset++
}

if ats[1]&0x20 != 0 {
offset++
}

if ats[2]&0x40 != 0 {
offset++
}

if len(ats) > offset {
return ats[offset:]
}
}

return nil
}

// Add cascade tags (0x88) in UID. See ISO/IEC 14443-3 sec. 6.4.4.
func ISO14443CascadeUID(uid []byte) (cascadedUID []byte) {
switch len(uid) {
case 7:
cascadedUID = make([]byte, 8)
cascadedUID[0] = 0x88
copy(cascadedUID[1:], uid)
case 10:
cascadedUID = make([]byte, 12)
cascadedUID[0] = 0x88
copy(cascadedUID[1:4], uid)
cascadedUID[4] = 0x88
copy(cascadedUID[5:], uid[3:])
case 4:
fallthrough
default:
cascadedUID = append(cascadedUID, uid...)
}

return
}
Loading

0 comments on commit bdcf5f9

Please sign in to comment.