iso8583
iso8583 copied to clipboard
Hexadecimal size calculation problems
Hello, I have some problems in the coding of the prefixes, since the size of the variable fields first converts them from int to string and from there to hexadecimal for which reason. If I have a size of 8 at the moment the library puts it in hexadecimal encoding as "3338". which should be 8. Additionally it is counting the size two by two and not one by one
Thanks, @anthonybastidas49 for pointing this out. Can you make a test case that has the expected result that fails? If you have coded a work around we are happy to merge a pull request. We will get to this issue as soon as we can.
Hi @anthonybastidas49! May I ask you to share some more information with us so we can fix the issue?
Yes, the calculation of the sizes for visa frames. in fields of variable length it is calculating it wrongly.
@anthonybastidas49 without any examples that demo the problem it's really hard for us to fix the issue :(
Can you give us an example where calculation does not work?
we can get back to it when we have more context
Reopen as I think this needs to be resolved.
I am willing to explain the problem via google meet.
@anthonybastidas49 if this issue is still relevant, let discuss it in Moov's slack channel #iso8583.
We can't fix the issue without more information. You can use different encodings for prefixes. If you don't need them to be converted to hex, use ASCII prefixer like this:
2: field.NewString(&field.Spec{
Length: 19,
Description: "Primary Account Number",
Enc: encoding.ASCII,
Pref: prefix.ASCII.LL,
}),
My guess is that he wants to encode the prefix as binary in hex.
package main
import (
"bytes"
"encoding/binary"
"encoding/hex"
"fmt"
"log"
"github.com/moov-io/iso8583"
"github.com/moov-io/iso8583/encoding"
"github.com/moov-io/iso8583/field"
"github.com/moov-io/iso8583/prefix"
)
type binaryL struct{}
func (p *binaryL) EncodeLength(maxLen, dataLen int) ([]byte, error) {
if dataLen != maxLen {
return nil, fmt.Errorf("field length: %d should be fixed: %d", dataLen, maxLen)
}
b := make([]byte, 1)
binary.PutUvarint(b, uint64(dataLen*2))
return b, nil
}
func (p *binaryL) DecodeLength(maxLen int, data []byte) (int, int, error) {
i, err := binary.ReadUvarint(bytes.NewReader(data))
if err != nil {
return 0, 0, err
}
dataLen := int(i)
if dataLen > maxLen {
return 0, 0, fmt.Errorf("data length %d is larger than maximum %d", i, maxLen)
}
return dataLen, 1, nil
}
func (p *binaryL) Inspect() string {
return "Binary.L"
}
func main() {
m := iso8583.NewMessage(&iso8583.MessageSpec{
Fields: map[int]field.Field{
0: field.NewString(&field.Spec{
Length: 4,
Description: "Message Type Indicator",
Enc: encoding.BCD,
Pref: prefix.BCD.Fixed,
}),
1: field.NewBitmap(&field.Spec{
Description: "Bitmap",
Enc: encoding.Binary,
Pref: prefix.Binary.Fixed,
}),
2: field.NewNumeric(&field.Spec{
Description: "Primary Account Number",
Enc: encoding.BCD,
Pref: &binaryL{},
}),
}})
m.MTI("0100")
_ = m.Field(2, "4761340000000019")
b, _ := m.Pack()
log.Println(hex.EncodeToString(b)) // output: 01004000000000000000104761340000000019
}
I hope that it was resolved by #193
if no, we can re-open the issue