package encoding import ( "bytes" "fmt" ) type GSM7Coder struct{} func (c *GSM7Coder) Encode(s string, buf *bytes.Buffer) error { // utf8 := *(*[]byte)(unsafe.Pointer(&s)) utf8 := []byte(s) var ( offset int = 1 bitshift byte = 0 leap, shift bool ) for index, septet := range utf8 { if septet > 0b01111111 { return fmt.Errorf("invalid character at index %d", index) } if index == 0 { continue } bitshift++ // log.Printf("Index:%-3d Offset:%-3d Bitshift:%-3d CurrentByte:%08b (%-3d) OffsetByte:%08b (%-3d) Leap:%5v", index, offset, bitshift, utf8[index], utf8[index], utf8[index-offset], utf8[index-offset], leap) mask := byte(255 >> (8 - bitshift)) masked := (mask & septet) << (8 - bitshift) // log.Printf("Index:%-3d Offset:%-3d Bitshift:%-3d Mask:%08b Masked:%08b", index, offset, bitshift, mask, masked) if leap { masked >>= 1 } utf8[index-offset] |= masked utf8[index] >>= bitshift if !leap { buf.WriteByte(utf8[index-offset]) } if index == len(utf8)-1 && utf8[index] > 0 { buf.WriteByte(utf8[index]) } // log.Printf("Index:%-3d Offset:%-3d Bitshift:%-3d CurrentByte:%08b (%-3d) OffsetByte:%08b (%-3d) Leap:%5v", index, offset, bitshift, utf8[index], utf8[index], utf8[index-offset], utf8[index-offset], leap) if bitshift >= 7 { if leap { // log.Printf("Shift at Index:%-3d Offset:%-3d Bitshift:%-3d", index, offset, bitshift) leap = false bitshift = 0 offset++ shift = true continue } // log.Printf("Leap at Index:%-3d Offset:%-3d Bitshift:%-3d", index, offset, bitshift) leap = true bitshift = 6 } if shift { offset = 1 } } return nil } func (c *GSM7Coder) Decode(buf *bytes.Buffer) (string, error) { gsm7 := buf.Bytes() var ( offset int = (len(gsm7) / 8) + 1 bitshift byte = 0 leap, shift bool ) outLength := len(gsm7)*8/7 lengthDiff := outLength - len(gsm7) gsm7 = append(gsm7, make([]byte, lengthDiff)...) // We don't care about the last byte // Unless it's the %8....... // We'll deal with that later for index := len(gsm7) - 2; index >= 0; index-- { octet := gsm7[index] bitshift = byte((index + 1) % 8) if bitshift == 7 { leap = true } // log.Printf("Index:%-3d Offset:%-3d Bitshift:%-3d CurrentByte:%08b (%-3d) OffsetByte(%-3d):%08b (%-3d) Leap:%5v", index, offset, bitshift, gsm7[index], gsm7[index], index+offset, gsm7[index+offset], gsm7[index+offset], leap) mask := byte(255 << (8 - bitshift)) masked := (mask & octet) >> (8 - bitshift) // log.Printf("Index:%-3d Offset:%-3d Bitshift:%-3d Mask:%08b Masked:%08b", index, offset, bitshift, mask, masked) if leap { InsertAt(&gsm7, index+offset, masked) } else { gsm7[index+offset] |= masked } // Remove last bitshift bits gsm7[index] <<= bitshift // Move the remaining bit once to the right to form septet instead of octet gsm7[index] >>= 1 // log.Printf("Index:%-3d Offset:%-3d Bitshift:%-3d CurrentByte:%08b (%-3d) OffsetByte(%-3d):%08b (%-3d) Leap:%5v", index, offset, bitshift, gsm7[index], gsm7[index], index+offset, gsm7[index+offset], gsm7[index+offset], leap) leap = false continue if !leap { buf.WriteByte(gsm7[index+offset]) } if index == len(gsm7)-1 && gsm7[index] > 0 { buf.WriteByte(gsm7[index]) } // log.Printf("Index:%-3d Offset:%-3d Bitshift:%-3d CurrentByte:%08b (%-3d) OffsetByte:%08b (%-3d) Leap:%5v", index, offset, bitshift, gsm7[index], gsm7[index], gsm7[index-offset], gsm7[index-offset], leap) if bitshift >= 7 { if leap { // log.Printf("Shift at Index:%-3d Offset:%-3d Bitshift:%-3d", index, offset, bitshift) leap = false bitshift = 0 offset++ shift = true continue } // log.Printf("Leap at Index:%-3d Offset:%-3d Bitshift:%-3d", index, offset, bitshift) leap = true bitshift = 6 } if shift { offset = 1 } } // log.Printf("Result: %+v", gsm7) // for _, v := range gsm7 { // log.Printf("%08b", v) // } return string(gsm7), nil } // Allocation free // Which means data MUST have space for value func InsertAt(data *[]byte, index int, value byte) { copy((*data)[index+1:], (*data)[index:]) (*data)[index] = value }