mirror of
https://github.com/tinygo-org/drivers.git
synced 2026-08-04 06:57:48 +00:00
failing CRC7 implementation
This commit is contained in:
+11
-7
@@ -32,7 +32,7 @@ func main() {
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
sdcard := sd.NewCard(spibus, SPI_CS_PIN.Set)
|
||||
sdcard := sd.NewSPICard(spibus, SPI_CS_PIN.Set)
|
||||
|
||||
err = sdcard.Init()
|
||||
if err != nil {
|
||||
@@ -47,20 +47,24 @@ func main() {
|
||||
data := csd.RawCopy()
|
||||
crc := sd.CRC7(data[:15])
|
||||
always1 := data[15]&(1<<7) != 0
|
||||
println("CSD not valid got", crc, "want", data[15]&^(1<<7), "always1:", always1)
|
||||
fmt.Printf("ourCRC7=%#b theirCRC7=%#b for data %d\n", crc, csd.CRC7(), data[:15])
|
||||
println("CSD not valid got", crc, "want", csd.CRC7(), "always1:", always1)
|
||||
return
|
||||
} else {
|
||||
println("CSD valid!")
|
||||
}
|
||||
|
||||
fmt.Printf("name=%s\ncsd=\n%s\n", pname, csd.String())
|
||||
return
|
||||
|
||||
var buf [512]byte
|
||||
for i := 1; i < 11; i += 1 {
|
||||
time.Sleep(time.Millisecond)
|
||||
err = sdcard.ReadBlock(uint32(i), buf[:])
|
||||
for i := 0; i < 11; i += 1 {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
err = sdcard.ReadBlock(int64(i), buf[:])
|
||||
if err != nil {
|
||||
println("err reading block", i, ":", err.Error())
|
||||
continue
|
||||
}
|
||||
fmt.Printf("block %d crc=%#x:\n\t%#x\n", i, sdcard.LastReadCRC(), buf[:])
|
||||
expectCRC := sd.CRC16(buf[:])
|
||||
fmt.Printf("block %d theircrc=%#x ourcrc=%#x:\n\t%#x\n", i, sdcard.LastReadCRC(), expectCRC, buf[:])
|
||||
}
|
||||
}
|
||||
|
||||
+80
-53
@@ -3,6 +3,7 @@ package sd
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"math"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"time"
|
||||
@@ -21,33 +22,36 @@ var (
|
||||
errNeed512 = errors.New("sd:need 512 bytes for I/O")
|
||||
errWrite = errors.New("sd:write")
|
||||
errWriteTimeout = errors.New("sd:write timeout")
|
||||
errOOB = errors.New("sd:oob block access")
|
||||
errNoblocks = errors.New("sd:no readable blocks")
|
||||
)
|
||||
|
||||
type digitalPinout func(b bool)
|
||||
|
||||
type Card struct {
|
||||
bus drivers.SPI
|
||||
cs digitalPinout
|
||||
bufcmd [6]byte
|
||||
buf [512]byte
|
||||
bufTok [1]byte
|
||||
kind CardKind
|
||||
cid CID
|
||||
csd CSD
|
||||
lastCRC uint16
|
||||
timers [2]timer
|
||||
type SPICard struct {
|
||||
bus drivers.SPI
|
||||
cs digitalPinout
|
||||
bufcmd [6]byte
|
||||
buf [512]byte
|
||||
bufTok [1]byte
|
||||
kind CardKind
|
||||
cid CID
|
||||
csd CSD
|
||||
lastCRC uint16
|
||||
timers [2]timer
|
||||
numblocks int64
|
||||
}
|
||||
|
||||
func NewCard(spi drivers.SPI, cs digitalPinout) *Card {
|
||||
return &Card{bus: spi, cs: cs}
|
||||
func NewSPICard(spi drivers.SPI, cs digitalPinout) *SPICard {
|
||||
return &SPICard{bus: spi, cs: cs}
|
||||
}
|
||||
|
||||
func (c *Card) csEnable(b bool) { c.cs(!b) }
|
||||
func (c *SPICard) csEnable(b bool) { c.cs(!b) }
|
||||
|
||||
// LastReadCRC returns the CRC for the last ReadBlock operation.
|
||||
func (c *Card) LastReadCRC() uint16 { return c.lastCRC }
|
||||
func (c *SPICard) LastReadCRC() uint16 { return c.lastCRC }
|
||||
|
||||
func (d *Card) Init() error {
|
||||
func (d *SPICard) Init() error {
|
||||
dummy := d.buf[:]
|
||||
for i := range dummy {
|
||||
dummy[i] = 0xFF
|
||||
@@ -92,7 +96,7 @@ func (d *Card) Init() error {
|
||||
status := byte(0)
|
||||
for i := 0; i < 3; i++ {
|
||||
var err error
|
||||
status, err = d.bus.Transfer(byte(0xFF))
|
||||
status, err = d.bus.Transfer(0xFF)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -103,7 +107,7 @@ func (d *Card) Init() error {
|
||||
|
||||
for i := 3; i < 4; i++ {
|
||||
var err error
|
||||
status, err = d.bus.Transfer(byte(0xFF))
|
||||
status, err = d.bus.Transfer(0xFF)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -143,7 +147,7 @@ func (d *Card) Init() error {
|
||||
return err
|
||||
}
|
||||
|
||||
statusb, err := d.bus.Transfer(byte(0xFF))
|
||||
statusb, err := d.bus.Transfer(0xFF)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -152,7 +156,7 @@ func (d *Card) Init() error {
|
||||
}
|
||||
// discard rest of ocr - contains allowed voltage range
|
||||
for i := 1; i < 4; i++ {
|
||||
d.bus.Transfer(byte(0xFF))
|
||||
d.bus.Transfer(0xFF)
|
||||
}
|
||||
}
|
||||
err = d.cmdEnsure0Status(CMD16_SET_BLOCKLEN, 0x0200, 0xff)
|
||||
@@ -169,20 +173,33 @@ func (d *Card) Init() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
nb := d.csd.NumberOfBlocks()
|
||||
if nb > math.MaxUint32 {
|
||||
return errCardNotSupported
|
||||
} else if nb == 0 {
|
||||
return errNoblocks
|
||||
}
|
||||
d.numblocks = int64(nb)
|
||||
return nil
|
||||
}
|
||||
|
||||
// ReadData reads 512 bytes from sdcard into dst.
|
||||
func (d *Card) ReadBlock(block uint32, dst []byte) error {
|
||||
func (d *SPICard) NumberOfBlocks() uint64 {
|
||||
return uint64(d.numblocks)
|
||||
}
|
||||
|
||||
// ReadBlock reads 512 bytes from sdcard into dst.
|
||||
func (d *SPICard) ReadBlock(block int64, dst []byte) error {
|
||||
if len(dst) != 512 {
|
||||
return errNeed512
|
||||
} else if block >= d.numblocks {
|
||||
return errOOB
|
||||
}
|
||||
|
||||
// use address if not SDHC card
|
||||
if d.kind != TypeSDHC {
|
||||
block <<= 9
|
||||
}
|
||||
err := d.cmdEnsure0Status(CMD17_READ_SINGLE_BLOCK, block, 0xFF)
|
||||
err := d.cmdEnsure0Status(CMD17_READ_SINGLE_BLOCK, uint32(block), 0xFF)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -198,23 +215,25 @@ func (d *Card) ReadBlock(block uint32, dst []byte) error {
|
||||
}
|
||||
|
||||
// skip CRC (2byte)
|
||||
hi, _ := d.bus.Transfer(byte(0xFF))
|
||||
lo, _ := d.bus.Transfer(byte(0xFF))
|
||||
hi, _ := d.bus.Transfer(0xFF)
|
||||
lo, _ := d.bus.Transfer(0xFF)
|
||||
d.lastCRC = uint16(hi)<<8 | uint16(lo)
|
||||
return nil
|
||||
}
|
||||
|
||||
// WriteBlock writes 512 bytes from dst to sdcard.
|
||||
func (d *Card) WriteBlock(block uint32, src []byte) error {
|
||||
func (d *SPICard) WriteBlock(block int64, src []byte) error {
|
||||
if len(src) != 512 {
|
||||
return errNeed512
|
||||
} else if block >= d.numblocks {
|
||||
return errOOB
|
||||
}
|
||||
|
||||
// use address if not SDHC card
|
||||
if d.kind != TypeSDHC {
|
||||
block <<= 9
|
||||
}
|
||||
err := d.cmdEnsure0Status(CMD24_WRITE_BLOCK, block, 0xFF)
|
||||
err := d.cmdEnsure0Status(CMD24_WRITE_BLOCK, uint32(block), 0xFF)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -229,11 +248,11 @@ func (d *Card) WriteBlock(block uint32, src []byte) error {
|
||||
}
|
||||
|
||||
// send dummy CRC (2 byte)
|
||||
d.bus.Transfer(byte(0xFF))
|
||||
d.bus.Transfer(byte(0xFF))
|
||||
d.bus.Transfer(0xFF)
|
||||
d.bus.Transfer(0xFF)
|
||||
|
||||
// Data Resp.
|
||||
r, err := d.bus.Transfer(byte(0xFF))
|
||||
r, err := d.bus.Transfer(0xFF)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -251,12 +270,12 @@ func (d *Card) WriteBlock(block uint32, src []byte) error {
|
||||
}
|
||||
|
||||
// CID returns a copy of the Card Identification Register value last read.
|
||||
func (d *Card) CID() CID { return d.cid }
|
||||
func (d *SPICard) CID() CID { return d.cid }
|
||||
|
||||
// CSD returns a copy of the Card Specific Data Register value last read.
|
||||
func (d *Card) CSD() CSD { return d.csd }
|
||||
func (d *SPICard) CSD() CSD { return d.csd }
|
||||
|
||||
func (d *Card) readCID() (CID, error) {
|
||||
func (d *SPICard) readCID() (CID, error) {
|
||||
buf := d.buf[len(d.buf)-16:]
|
||||
if err := d.readRegister(CMD10_SEND_CID, buf); err != nil {
|
||||
return CID{}, err
|
||||
@@ -264,7 +283,7 @@ func (d *Card) readCID() (CID, error) {
|
||||
return DecodeCID(buf)
|
||||
}
|
||||
|
||||
func (d *Card) readCSD() (CSD, error) {
|
||||
func (d *SPICard) readCSD() (CSD, error) {
|
||||
buf := d.buf[len(d.buf)-16:]
|
||||
if err := d.readRegister(CMD9_SEND_CSD, buf); err != nil {
|
||||
return CSD{}, err
|
||||
@@ -272,7 +291,7 @@ func (d *Card) readCSD() (CSD, error) {
|
||||
return DecodeCSD(buf)
|
||||
}
|
||||
|
||||
func (d *Card) readRegister(cmd uint8, dst []byte) error {
|
||||
func (d *SPICard) readRegister(cmd uint8, dst []byte) error {
|
||||
err := d.cmdEnsure0Status(cmd, 0, 0xFF)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -282,20 +301,20 @@ func (d *Card) readRegister(cmd uint8, dst []byte) error {
|
||||
}
|
||||
// transfer data
|
||||
for i := uint16(0); i < 16; i++ {
|
||||
r, err := d.bus.Transfer(byte(0xFF))
|
||||
r, err := d.bus.Transfer(0xFF)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dst[i] = r
|
||||
}
|
||||
// skip CRC.
|
||||
d.bus.Transfer(byte(0xFF))
|
||||
d.bus.Transfer(byte(0xFF))
|
||||
d.bus.Transfer(0xFF)
|
||||
d.bus.Transfer(0xFF)
|
||||
d.csEnable(false)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Card) appCmd(cmd byte, arg uint32) (response1, error) {
|
||||
func (d *SPICard) appCmd(cmd byte, arg uint32) (response1, error) {
|
||||
status, err := d.cmd(CMD55_APP_CMD, 0, 0xFF)
|
||||
if err != nil {
|
||||
return status, err
|
||||
@@ -303,7 +322,7 @@ func (d *Card) appCmd(cmd byte, arg uint32) (response1, error) {
|
||||
return d.cmd(cmd, arg, 0xFF)
|
||||
}
|
||||
|
||||
func (d *Card) cmdEnsure0Status(cmd byte, arg uint32, crc byte) error {
|
||||
func (d *SPICard) cmdEnsure0Status(cmd byte, arg uint32, crc byte) error {
|
||||
status, err := d.cmd(cmd, arg, crc)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -314,7 +333,17 @@ func (d *Card) cmdEnsure0Status(cmd byte, arg uint32, crc byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Card) cmd(cmd byte, arg uint32, crc byte) (response1, error) {
|
||||
func putCmd(dst []byte, cmd byte, arg uint32) {
|
||||
if len(dst) < 6 {
|
||||
panic("bad buflength")
|
||||
}
|
||||
dst[0] = 0x40 | cmd
|
||||
binary.BigEndian.PutUint32(dst[1:5], arg)
|
||||
dst[5] = CRC7(dst[:5])<<1 | 1 // CRC and stop bit.
|
||||
}
|
||||
|
||||
// 0100000000000000000000000000000000000000
|
||||
func (d *SPICard) cmd(cmd byte, arg uint32, crc byte) (response1, error) {
|
||||
d.csEnable(true)
|
||||
|
||||
if cmd != 12 {
|
||||
@@ -322,9 +351,8 @@ func (d *Card) cmd(cmd byte, arg uint32, crc byte) (response1, error) {
|
||||
}
|
||||
|
||||
// create and send the command
|
||||
buf := d.bufcmd[:]
|
||||
buf[0] = 0x40 | cmd
|
||||
binary.BigEndian.PutUint32(buf[1:5], arg)
|
||||
buf := d.bufcmd[:6]
|
||||
putCmd(buf, cmd, arg)
|
||||
buf[5] = crc
|
||||
err := d.bus.Tx(buf, nil)
|
||||
if err != nil {
|
||||
@@ -332,14 +360,13 @@ func (d *Card) cmd(cmd byte, arg uint32, crc byte) (response1, error) {
|
||||
}
|
||||
if cmd == 12 {
|
||||
// skip 1 byte
|
||||
d.bus.Transfer(byte(0xFF))
|
||||
d.bus.Transfer(0xFF)
|
||||
}
|
||||
|
||||
// wait for the response (response[7] == 0)
|
||||
d.buf[0] = 0xFF
|
||||
dummy := d.buf[:1]
|
||||
buf[0] = 0xFF
|
||||
for i := 0; i < 0xFFFF; i++ {
|
||||
d.bus.Tx(dummy, d.bufTok[:])
|
||||
d.bus.Tx(buf[:1], d.bufTok[:])
|
||||
response := response1(d.bufTok[0])
|
||||
if (response & 0x80) == 0 {
|
||||
return response, nil
|
||||
@@ -349,15 +376,15 @@ func (d *Card) cmd(cmd byte, arg uint32, crc byte) (response1, error) {
|
||||
// TODO
|
||||
//// timeout
|
||||
d.csEnable(false)
|
||||
d.bus.Transfer(byte(0xFF))
|
||||
d.bus.Transfer(0xFF)
|
||||
|
||||
return 0xFF, nil // -1
|
||||
}
|
||||
|
||||
func (d *Card) waitNotBusy(timeout time.Duration) error {
|
||||
func (d *SPICard) waitNotBusy(timeout time.Duration) error {
|
||||
tm := d.timers[1].setTimeout(timeout)
|
||||
for !tm.expired() {
|
||||
r, err := d.bus.Transfer(byte(0xFF))
|
||||
r, err := d.bus.Transfer(0xFF)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -369,12 +396,12 @@ func (d *Card) waitNotBusy(timeout time.Duration) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Card) waitStartBlock() error {
|
||||
func (d *SPICard) waitStartBlock() error {
|
||||
status := byte(0xFF)
|
||||
tm := d.timers[0].setTimeout(300 * time.Millisecond)
|
||||
for !tm.expired() {
|
||||
var err error
|
||||
status, err = d.bus.Transfer(byte(0xFF))
|
||||
status, err = d.bus.Transfer(0xFF)
|
||||
if err != nil {
|
||||
d.csEnable(false)
|
||||
return err
|
||||
|
||||
+58
-1
@@ -5,7 +5,7 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCRC(t *testing.T) {
|
||||
func TestCRC16(t *testing.T) {
|
||||
tests := []struct {
|
||||
block string
|
||||
wantcrc uint16
|
||||
@@ -27,3 +27,60 @@ func TestCRC(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCRC7(t *testing.T) {
|
||||
const cmdSendMask = 0x40
|
||||
tests := []struct {
|
||||
data []byte
|
||||
wantCRC uint8
|
||||
}{
|
||||
{ // See CRC7 Examples from section 4.5 of the SD Card Physical Layer Simplified Specification.
|
||||
data: []byte{cmdSendMask, 5: 0}, // CMD0, arg=0
|
||||
wantCRC: 0b1001010,
|
||||
},
|
||||
{
|
||||
data: []byte{cmdSendMask | 17, 5: 0}, // CMD17, arg=0
|
||||
wantCRC: 0b0101010,
|
||||
},
|
||||
{
|
||||
data: []byte{17, 4: 0b1001, 5: 0}, // Response of CMD17
|
||||
wantCRC: 0b0110011,
|
||||
},
|
||||
{ // CSD for a 8GB card.
|
||||
data: []byte{64, 14, 0, 50, 83, 89, 0, 0, 60, 1, 127, 128, 10, 64, 0},
|
||||
wantCRC: 0b1100101,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
gotcrc := CRC7(tt.data[:])
|
||||
if gotcrc != tt.wantCRC {
|
||||
t.Errorf("got crc=%#b, want=%#b", gotcrc, tt.wantCRC)
|
||||
}
|
||||
}
|
||||
|
||||
cmdTests := []struct {
|
||||
cmd byte
|
||||
arg uint32
|
||||
wantCRC uint8
|
||||
}{
|
||||
{
|
||||
cmd: CMD0_GO_IDLE_STATE,
|
||||
arg: 0,
|
||||
wantCRC: 0x95,
|
||||
},
|
||||
{
|
||||
cmd: CMD8_SEND_IF_COND,
|
||||
arg: 0x1AA,
|
||||
wantCRC: 0x87,
|
||||
},
|
||||
}
|
||||
var dst [6]byte
|
||||
for _, test := range cmdTests {
|
||||
putCmd(dst[:], test.cmd, test.arg)
|
||||
gotcrc := dst[5]
|
||||
if gotcrc != test.wantCRC {
|
||||
t.Errorf("got crc=%#x, want=%#x", gotcrc, test.wantCRC)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+49
-15
@@ -196,6 +196,15 @@ func (c *CSD) DeviceCapacity() (size uint64) {
|
||||
return size
|
||||
}
|
||||
|
||||
// NumberOfBlocks returns amount of readable blocks in the device given by Capacity/ReadBlockLength.
|
||||
func (c *CSD) NumberOfBlocks() (numBlocks uint64) {
|
||||
rblocks := c.ReadBlockLen()
|
||||
if rblocks == 0 {
|
||||
return 0
|
||||
}
|
||||
return c.DeviceCapacity() / uint64(rblocks)
|
||||
}
|
||||
|
||||
// After byte 5 CSDv1 and CSDv2 differ in structure at some fields.
|
||||
|
||||
// DeviceCapacity returns the device capacity in bytes.
|
||||
@@ -440,9 +449,9 @@ func b2u8(b bool) uint8 {
|
||||
}
|
||||
|
||||
// CRC16 computes the CRC16 checksum for a given payload using the CRC-16-CCITT polynomial.
|
||||
func CRC16(buf []byte) (sum uint16) {
|
||||
func CRC16(buf []byte) (crc uint16) {
|
||||
const poly uint16 = 0x1021 // Generator polynomial G(x) = x^16 + x^12 + x^5 + 1
|
||||
var crc uint16 = 0x0000 // Initial value
|
||||
|
||||
for _, b := range buf {
|
||||
crc ^= (uint16(b) << 8) // Shift byte into MSB of crc
|
||||
for i := 0; i < 8; i++ { // Process each bit
|
||||
@@ -457,19 +466,44 @@ func CRC16(buf []byte) (sum uint16) {
|
||||
}
|
||||
|
||||
// CRC7 computes the CRC7 checksum for a given payload using the polynomial x^7 + x^3 + 1.
|
||||
func CRC7(data []byte) uint8 {
|
||||
const poly uint8 = 0x09 // Generator polynomial G(x) = x^7 + x^3 + 1
|
||||
var crc uint8 = 0x00 // Initial value
|
||||
|
||||
func CRC7(data []byte) (crc uint8) {
|
||||
for _, b := range data {
|
||||
crc ^= b // Initial XOR
|
||||
for i := 0; i < 8; i++ { // Process each bit
|
||||
if crc&0x80 != 0 {
|
||||
crc = (crc << 1) ^ poly
|
||||
} else {
|
||||
crc <<= 1
|
||||
}
|
||||
}
|
||||
crc = crc7_table[crc^b]
|
||||
}
|
||||
return crc >> 1
|
||||
return crc
|
||||
}
|
||||
|
||||
var crc7_table = [256]byte{
|
||||
0x00, 0x12, 0x24, 0x36, 0x48, 0x5a, 0x6c, 0x7e,
|
||||
0x90, 0x82, 0xb4, 0xa6, 0xd8, 0xca, 0xfc, 0xee,
|
||||
0x32, 0x20, 0x16, 0x04, 0x7a, 0x68, 0x5e, 0x4c,
|
||||
0xa2, 0xb0, 0x86, 0x94, 0xea, 0xf8, 0xce, 0xdc,
|
||||
0x64, 0x76, 0x40, 0x52, 0x2c, 0x3e, 0x08, 0x1a,
|
||||
0xf4, 0xe6, 0xd0, 0xc2, 0xbc, 0xae, 0x98, 0x8a,
|
||||
0x56, 0x44, 0x72, 0x60, 0x1e, 0x0c, 0x3a, 0x28,
|
||||
0xc6, 0xd4, 0xe2, 0xf0, 0x8e, 0x9c, 0xaa, 0xb8,
|
||||
0xc8, 0xda, 0xec, 0xfe, 0x80, 0x92, 0xa4, 0xb6,
|
||||
0x58, 0x4a, 0x7c, 0x6e, 0x10, 0x02, 0x34, 0x26,
|
||||
0xfa, 0xe8, 0xde, 0xcc, 0xb2, 0xa0, 0x96, 0x84,
|
||||
0x6a, 0x78, 0x4e, 0x5c, 0x22, 0x30, 0x06, 0x14,
|
||||
0xac, 0xbe, 0x88, 0x9a, 0xe4, 0xf6, 0xc0, 0xd2,
|
||||
0x3c, 0x2e, 0x18, 0x0a, 0x74, 0x66, 0x50, 0x42,
|
||||
0x9e, 0x8c, 0xba, 0xa8, 0xd6, 0xc4, 0xf2, 0xe0,
|
||||
0x0e, 0x1c, 0x2a, 0x38, 0x46, 0x54, 0x62, 0x70,
|
||||
0x82, 0x90, 0xa6, 0xb4, 0xca, 0xd8, 0xee, 0xfc,
|
||||
0x12, 0x00, 0x36, 0x24, 0x5a, 0x48, 0x7e, 0x6c,
|
||||
0xb0, 0xa2, 0x94, 0x86, 0xf8, 0xea, 0xdc, 0xce,
|
||||
0x20, 0x32, 0x04, 0x16, 0x68, 0x7a, 0x4c, 0x5e,
|
||||
0xe6, 0xf4, 0xc2, 0xd0, 0xae, 0xbc, 0x8a, 0x98,
|
||||
0x76, 0x64, 0x52, 0x40, 0x3e, 0x2c, 0x1a, 0x08,
|
||||
0xd4, 0xc6, 0xf0, 0xe2, 0x9c, 0x8e, 0xb8, 0xaa,
|
||||
0x44, 0x56, 0x60, 0x72, 0x0c, 0x1e, 0x28, 0x3a,
|
||||
0x4a, 0x58, 0x6e, 0x7c, 0x02, 0x10, 0x26, 0x34,
|
||||
0xda, 0xc8, 0xfe, 0xec, 0x92, 0x80, 0xb6, 0xa4,
|
||||
0x78, 0x6a, 0x5c, 0x4e, 0x30, 0x22, 0x14, 0x06,
|
||||
0xe8, 0xfa, 0xcc, 0xde, 0xa0, 0xb2, 0x84, 0x96,
|
||||
0x2e, 0x3c, 0x0a, 0x18, 0x66, 0x74, 0x42, 0x50,
|
||||
0xbe, 0xac, 0x9a, 0x88, 0xf6, 0xe4, 0xd2, 0xc0,
|
||||
0x1c, 0x0e, 0x38, 0x2a, 0x54, 0x46, 0x70, 0x62,
|
||||
0x8c, 0x9e, 0xa8, 0xba, 0xc4, 0xd6, 0xe0, 0xf2,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user