v
v copied to clipboard
Add std go like RSA and Binary
Describe the feature
rsa like go and binary read like go
Use Case
its important everytime
Proposed Solution
No response
Other Information
No response
Acknowledgements
- [ ] I may be able to implement this feature request
- [ ] This feature might incur a breaking change
Version used
recent
Environment details (OS name and version, etc.)
all
Can you describe more about this feature like RSA encryption or any other language?
Can you describe more about this feature like RSA encryption or any other language?
you can check both on go repo. Binary: https://github.com/golang/go/tree/master/src/encoding/binary Rsa: https://github.com/golang/go/tree/master/src/crypto/rsa
Can be convert this binary go code to v code?
package main
import (
"errors"
"io"
"math"
"reflect"
"sync"
"fmt"
"strings"
)
type ByteOrder interface {
Uint16([]byte) uint16
Uint32([]byte) uint32
Uint64([]byte) uint64
}
var LittleEndian littleEndian
type littleEndian struct{}
func (littleEndian) Uint16(b []byte) uint16 {
return uint16(b[0]) | uint16(b[1])<<8
}
func (littleEndian) Uint32(b []byte) uint32 {
return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
}
func (littleEndian) Uint64(b []byte) uint64 {
return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |
uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
}
func Read(r io.Reader, order ByteOrder, data interface{}) error {
if n := intDataSize(data); n != 0 {
bs := make([]byte, n)
if _, err := io.ReadFull(r, bs); err != nil {
return err
}
switch data := data.(type) {
case *bool:
*data = bs[0] != 0
case *int8:
*data = int8(bs[0])
case *uint8:
*data = bs[0]
case *int16:
*data = int16(order.Uint16(bs))
case *uint16:
*data = order.Uint16(bs)
case *int32:
*data = int32(order.Uint32(bs))
case *uint32:
*data = order.Uint32(bs)
case *int64:
*data = int64(order.Uint64(bs))
case *uint64:
*data = order.Uint64(bs)
case *float32:
*data = math.Float32frombits(order.Uint32(bs))
case *float64:
*data = math.Float64frombits(order.Uint64(bs))
case []bool:
for i, x := range bs {
data[i] = x != 0
}
case []int8:
for i, x := range bs {
data[i] = int8(x)
}
case []uint8:
copy(data, bs)
case []int16:
for i := range data {
data[i] = int16(order.Uint16(bs[2*i:]))
}
case []uint16:
for i := range data {
data[i] = order.Uint16(bs[2*i:])
}
case []int32:
for i := range data {
data[i] = int32(order.Uint32(bs[4*i:]))
}
case []uint32:
for i := range data {
data[i] = order.Uint32(bs[4*i:])
}
case []int64:
for i := range data {
data[i] = int64(order.Uint64(bs[8*i:]))
}
case []uint64:
for i := range data {
data[i] = order.Uint64(bs[8*i:])
}
case []float32:
for i := range data {
data[i] = math.Float32frombits(order.Uint32(bs[4*i:]))
}
case []float64:
for i := range data {
data[i] = math.Float64frombits(order.Uint64(bs[8*i:]))
}
default:
n = 0
}
if n != 0 {
return nil
}
}
v := reflect.ValueOf(data)
size := -1
switch v.Kind() {
case reflect.Pointer:
v = v.Elem()
size = dataSize(v)
case reflect.Slice:
size = dataSize(v)
}
if size < 0 {
return errors.New("Read: invalid type " + reflect.TypeOf(data).String())
}
d := &decoder{order: order, buf: make([]byte, size)}
if _, err := io.ReadFull(r, d.buf); err != nil {
return err
}
d.value(v)
return nil
}
func Size(v interface{}) int {
return dataSize(reflect.Indirect(reflect.ValueOf(v)))
}
var structSize sync.Map
func dataSize(v reflect.Value) int {
switch v.Kind() {
case reflect.Slice:
if s := sizeof(v.Type().Elem()); s >= 0 {
return s * v.Len()
}
return -1
case reflect.Struct:
t := v.Type()
if size, ok := structSize.Load(t); ok {
return size.(int)
}
size := sizeof(t)
structSize.Store(t, size)
return size
default:
return sizeof(v.Type())
}
}
func sizeof(t reflect.Type) int {
switch t.Kind() {
case reflect.Array:
if s := sizeof(t.Elem()); s >= 0 {
return s * t.Len()
}
case reflect.Struct:
sum := 0
for i, n := 0, t.NumField(); i < n; i++ {
s := sizeof(t.Field(i).Type)
if s < 0 {
return -1
}
sum += s
}
return sum
case reflect.Bool,
reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128:
return int(t.Size())
}
return -1
}
type coder struct {
order ByteOrder
buf []byte
offset int
}
type decoder coder
func (d *decoder) bool() bool {
x := d.buf[d.offset]
d.offset++
return x != 0
}
func (d *decoder) uint8() uint8 {
x := d.buf[d.offset]
d.offset++
return x
}
func (d *decoder) uint16() uint16 {
x := d.order.Uint16(d.buf[d.offset : d.offset+2])
d.offset += 2
return x
}
func (d *decoder) uint32() uint32 {
x := d.order.Uint32(d.buf[d.offset : d.offset+4])
d.offset += 4
return x
}
func (d *decoder) uint64() uint64 {
x := d.order.Uint64(d.buf[d.offset : d.offset+8])
d.offset += 8
return x
}
func (d *decoder) int8() int8 { return int8(d.uint8()) }
func (d *decoder) int16() int16 { return int16(d.uint16()) }
func (d *decoder) int32() int32 { return int32(d.uint32()) }
func (d *decoder) int64() int64 { return int64(d.uint64()) }
func (d *decoder) value(v reflect.Value) {
switch v.Kind() {
case reflect.Array:
l := v.Len()
for i := 0; i < l; i++ {
d.value(v.Index(i))
}
case reflect.Struct:
t := v.Type()
l := v.NumField()
for i := 0; i < l; i++ {
if v := v.Field(i); v.CanSet() || t.Field(i).Name != "_" {
d.value(v)
} else {
d.skip(v)
}
}
case reflect.Slice:
l := v.Len()
for i := 0; i < l; i++ {
d.value(v.Index(i))
}
case reflect.Bool:
v.SetBool(d.bool())
case reflect.Int8:
v.SetInt(int64(d.int8()))
case reflect.Int16:
v.SetInt(int64(d.int16()))
case reflect.Int32:
v.SetInt(int64(d.int32()))
case reflect.Int64:
v.SetInt(d.int64())
case reflect.Uint8:
v.SetUint(uint64(d.uint8()))
case reflect.Uint16:
v.SetUint(uint64(d.uint16()))
case reflect.Uint32:
v.SetUint(uint64(d.uint32()))
case reflect.Uint64:
v.SetUint(d.uint64())
case reflect.Float32:
v.SetFloat(float64(math.Float32frombits(d.uint32())))
case reflect.Float64:
v.SetFloat(math.Float64frombits(d.uint64()))
case reflect.Complex64:
v.SetComplex(complex(
float64(math.Float32frombits(d.uint32())),
float64(math.Float32frombits(d.uint32())),
))
case reflect.Complex128:
v.SetComplex(complex(
math.Float64frombits(d.uint64()),
math.Float64frombits(d.uint64()),
))
}
}
func (d *decoder) skip(v reflect.Value) {
d.offset += dataSize(v)
}
func intDataSize(data interface{}) int {
switch data := data.(type) {
case bool, int8, uint8, *bool, *int8, *uint8:
return 1
case []bool:
return len(data)
case []int8:
return len(data)
case []uint8:
return len(data)
case int16, uint16, *int16, *uint16:
return 2
case []int16:
return 2 * len(data)
case []uint16:
return 2 * len(data)
case int32, uint32, *int32, *uint32:
return 4
case []int32:
return 4 * len(data)
case []uint32:
return 4 * len(data)
case int64, uint64, *int64, *uint64:
return 8
case []int64:
return 8 * len(data)
case []uint64:
return 8 * len(data)
case float32, *float32:
return 4
case float64, *float64:
return 8
case []float32:
return 4 * len(data)
case []float64:
return 8 * len(data)
}
return 0
}
func main() {
r := strings.NewReader("\x01\x00\x00\x00\x00\x00\x00\x00")
var data int32
order := LittleEndian
err := Read(r, order, &data)
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println(data)
}
}
I converted in php but can't do it in vlang:
<?php
interface ByteOrder {
public function Uint16($b);
public function Uint32($b);
public function Uint64($b);
}
class littleEndian implements ByteOrder {
public function Uint16($b) {
return $b[0] | $b[1] << 8;
}
public function Uint32($b) {
return $b[0] | $b[1] << 8 | $b[2] << 16 | $b[3] << 24;
}
public function Uint64($b) {
return $b[0] | $b[1] << 8 | $b[2] << 16 | $b[3] << 24 |
$b[4] << 32 | $b[5] << 40 | $b[6] << 48 | $b[7] << 56;
}
}
function Read($r, $order, &$data) {
if ($n = intDataSize($data)) {
$bs = fread($r, $n);
if ($bs === false) {
return false;
}
switch (gettype($data)) {
case "boolean":
$data = $bs[0] != 0;
break;
case "integer":
$data = $bs[0];
break;
case "float":
$data = unpack("f", pack("V", $order->Uint32($bs)))[1];
break;
case "double":
$data = unpack("d", pack("P", $order->Uint64($bs)))[1];
break;
case "array":
foreach ($bs as $i => $x) {
$data[$i] = $x != 0;
}
break;
}
return true;
}
$v = $data;
$size = -1;
switch (gettype($v)) {
case "array":
$size = dataSize($v);
break;
case "object":
$size = dataSize($v);
break;
}
if ($size < 0) {
return false;
}
$d = new decoder($order, array_fill(0, $size, 0), 0);
if (fread($r, $d->buf) === false) {
return false;
}
$d->value($v);
return true;
}
function Size($v) {
return dataSize($v);
}
$structSize = array();
function dataSize($v) {
switch (gettype($v)) {
case "array":
if ($s = customSizeOf($v[0])) {
return $s * count($v);
}
return -1;
case "object":
$t = get_class($v);
global $structSize;
if (array_key_exists($t, $structSize)) {
return $structSize[$t];
}
$size = customSizeOf($t);
$structSize[$t] = $size;
return $size;
default:
return customSizeOf($v);
}
}
function customSizeOf($t) {
switch (gettype($t)) {
case "array":
if ($s = customSizeOf($t[0])) {
return $s * count($t);
}
break;
case "object":
$sum = 0;
foreach ($t as $field) {
$s = customSizeOf($field);
if ($s < 0) {
return -1;
}
$sum += $s;
}
return $sum;
case "boolean":
case "integer":
case "double":
return 1;
}
return -1;
}
class coder {
public $order;
public $buf;
public $offset;
public function __construct($order, $buf, $offset) {
$this->order = $order;
$this->buf = $buf;
$this->offset = $offset;
}
}
class decoder extends coder {
public function bool() {
$x = $this->buf[$this->offset];
$this->offset++;
return $x != 0;
}
public function uint8() {
$x = $this->buf[$this->offset];
$this->offset++;
return $x;
}
public function uint16() {
$x = $this->order->Uint16(array_slice($this->buf, $this->offset, 2));
$this->offset += 2;
return $x;
}
public function uint32() {
$x = $this->order->Uint32(array_slice($this->buf, $this->offset, 4));
$this->offset += 4;
return $x;
}
public function uint64() {
$x = $this->order->Uint64(array_slice($this->buf, $this->offset, 8));
$this->offset += 8;
return $x;
}
public function int8() {
return (int)$this->uint8();
}
public function int16() {
return (int)$this->uint16();
}
public function int32() {
return (int)$this->uint32();
}
public function int64() {
return (int)$this->uint64();
}
public function value(&$v) {
switch (gettype($v)) {
case "array":
foreach ($v as $i => $x) {
$this->value($v[$i]);
}
break;
case "object":
foreach ($v as $field) {
if ($field->canSet() || $field->name != "_") {
$this->value($field);
} else {
$this->skip($field);
}
}
break;
case "boolean":
$v = $this->bool();
break;
case "integer":
$v = $this->int32();
break;
case "double":
$v = $this->float64();
break;
}
}
public function skip(&$v) {
$this->offset += dataSize($v);
}
}
function intDataSize($data) {
switch (gettype($data)) {
case "boolean":
case "integer":
return 1;
case "double":
return 8;
case "array":
return count($data);
}
return 0;
}
$r = fopen("php://memory", "r+");
fwrite($r, "\x01\x00\x00\x00\x00\x00\x00\x00");
rewind($r);
$data = 0;
$order = new littleEndian();
if (Read($r, $order, $data)) {
echo ord($data);
} else {
echo "Error";
}
?>
There are already encoding.binary in the v modules, and rsa is considered deprecated, the stock already has support more recent alternative