Skip to content

Commit

Permalink
feat(contrib/qxip/hash): add sha1, md5, base64, hmac (#5371)
Browse files Browse the repository at this point in the history
* feat(contrib/qxip/hash): add sha1, md5, b64

* feat(contrib/qxip/hash): extend coverage

* feat(contrib/qxip/hash): extend coverage

* feat(contrib/qxip/hash): test checkpoint

* feat(contrib/qxip/hash): test checkpoint

* feat(contrib/qxip/hash): fix readme

* feat(contrib/qxip/hash): add hmac

* feat(contrib/qxip/hash): test hmac

* feat(contrib/qxip/hash): merge suggestion

Co-authored-by: Scott Anderson <sanderson@users.noreply.github.com>

* feat(contrib/qxip/hash): merge suggestion

Co-authored-by: Scott Anderson <sanderson@users.noreply.github.com>

* feat(contrib/qxip/hash): merge suggestion

Co-authored-by: Scott Anderson <sanderson@users.noreply.github.com>

* feat(contrib/qxip/hash): merge suggestion

Co-authored-by: Scott Anderson <sanderson@users.noreply.github.com>

* feat(contrib/qxip/hash): merge suggestion

Co-authored-by: Scott Anderson <sanderson@users.noreply.github.com>

* feat(contrib/qxip/hash): merge suggestion

Co-authored-by: Scott Anderson <sanderson@users.noreply.github.com>

* feat(contrib/qxip/hash): merge suggestion

Co-authored-by: Scott Anderson <sanderson@users.noreply.github.com>

* feat(contrib/qxip/hash): regenerate

Co-authored-by: Scott Anderson <sanderson@users.noreply.github.com>
  • Loading branch information
lmangani and sanderson committed Jan 24, 2023
1 parent 175ec44 commit 1eba4ff
Show file tree
Hide file tree
Showing 5 changed files with 392 additions and 7 deletions.
2 changes: 1 addition & 1 deletion libflux/go/libflux/buildinfo.gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ var sourceHashes = map[string]string{
"stdlib/contrib/chobbs/discord/discord.flux": "bbda9aaee1966d67d310dc099d00476adda777394a1af279d447e4524e0d5e58",
"stdlib/contrib/jsternberg/influxdb/influxdb.flux": "afc52f2e31d5e063e318b752d077c58189317c373494563ea0895cdcdea49074",
"stdlib/contrib/qxip/clickhouse/clickhouse.flux": "8ad86d9c3c7a4271178d5e2fa9bb850856363cf470d92c3f5010b6de9e770db1",
"stdlib/contrib/qxip/hash/hash.flux": "abf7de64cbecd3f1019058be5240ba7289355df80b1771ca253f2dca857b9b1f",
"stdlib/contrib/qxip/hash/hash.flux": "25919a81b663b1f08e8f89df080c2cc5a32c40f0892ed1643d2d321e069b4fd4",
"stdlib/contrib/qxip/logql/logql.flux": "f855e5a58efd4332c63bbdbb41efc9522c97722c44202f4b26c5226c89e7a646",
"stdlib/contrib/rhajek/bigpanda/bigpanda.flux": "0f4d43a7ae08f0ce5e00a746082dbdae06008bcd69cb00b52f0b4f1bb10b7323",
"stdlib/contrib/sranka/opsgenie/opsgenie.flux": "5313b78a30ffb01c606397c9bea954bdd4ca06c44663268bab1e0f706fc6d2c5",
Expand Down
55 changes: 49 additions & 6 deletions stdlib/contrib/qxip/hash/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,20 @@ Example:
```
import "contrib/qxip/hash"
a = hash.sha256("Hello, world!")
// a is "315f5bdb76d078c43b8ac0064e4a0164612b1fce77c869345bfc94c75894edd3"
a = hash.sha256(v: "Hello, world!")
```

## hash.sha1
The `hash.sha256()` function converts a single string to a hash using sha256.

Example:

```
import "contrib/qxip/hash"
a = hash.sha1(v: "Hello, world!")
```

## hash.xxhash64
The `hash.xxhash64()` function converts a single string to a hash using xxhash64.

Expand All @@ -21,9 +32,9 @@ Example:
```
import "contrib/qxip/hash"
a = hash.xxhash64("Hello, world!")
// a is "17691043854468224118"
a = hash.xxhash64(v: "Hello, world!")
```

## hash.cityhash64
The `hash.cityhash64()` function converts a single string to hash using cityhash64.

Expand All @@ -32,8 +43,40 @@ Example:
```
import "contrib/qxip/hash"
a = hash.cityhash64("Hello, world!")
// a is "2359500134450972198"
a = hash.cityhash64(v: "Hello, world!")
```

## hash.md5
The `hash.md5()` function converts a single string to hash using MD5.

Example:

```
import "contrib/qxip/hash"
a = hash.md5(v: "Hello, world!")
```

## hash.b64
The `hash.b64()` function converts a single string to a Base64 string.

Example:

```
import "contrib/qxip/hash"
a = hash.b64(v: "Hello, world!")
```

## hash.hmac
The `hash.hmac()` function converts a string and key pair to sha1 signed Base64 string.

Example:

```
import "contrib/qxip/hash"
a = hash.hmac(v: "helloworld", k: "123456")
```

## Contact
Expand Down
81 changes: 81 additions & 0 deletions stdlib/contrib/qxip/hash/hash.flux
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,26 @@ package hash
// tag: type-conversion
builtin sha256 : (v: A) => string

// sha1 converts a string value to a hexadecimal hash using the SHA-1 hash algorithm.
//
// ## Parameters
//
// - v: String to hash.
//
// ## Examples
// ### Convert a string to a SHA-1 hash
// ```no_run
// import "contrib/qxip/hash"
//
// hash.sha1(v: "Hello, world!")
//
// // Returns 315f5bdb76d078c43b8ac0064e4a0164612b1fce77c869345bfc94c75894edd3
// ```
//
// ## Metadata
// tag: type-conversion
builtin sha1 : (v: A) => string

// xxhash64 converts a string value to a 64-bit hexadecimal hash using the xxHash algorithm.
//
// ## Parameters
Expand Down Expand Up @@ -66,3 +86,64 @@ builtin xxhash64 : (v: A) => string
// ## Metadata
// tag: type-conversion
builtin cityhash64 : (v: A) => string

// b64 converts a string value to a Base64 string.
//
// ## Parameters
//
// - v: String to hash.
//
// ## Examples
// ### Convert a string to a Base64 string
// ```no_run
// import "contrib/qxip/hash"
//
// hash.b64(v: "Hello, world!")
//
// // Returns 2359500134450972198
// ```
//
// ## Metadata
// tag: type-conversion
builtin b64 : (v: A) => string

// md5 converts a string value to an MD5 hash.
//
// ## Parameters
//
// - v: String to hash.
//
// ## Examples
// ### Convert a string to an MD5 hash
// ```no_run
// import "contrib/qxip/hash"
//
// hash.md5(v: "Hello, world!")
//
// // Returns 2359500134450972198
// ```
//
// ## Metadata
// tag: type-conversion
builtin md5 : (v: A) => string

// hmac converts a string value to an MD5-signed SHA-1 hash.
//
// ## Parameters
//
// - v: String to hash.
// - k: Key to sign hash.
//
// ## Examples
// ### Convert a string and key to a base64-signed hash
// ```no_run
// import "contrib/qxip/hash"
//
// hash.hmac(v: "helloworld", k: "123456")
//
// // Returns 75B5ueLnnGepYvh+KoevTzXCrjc=
// ```
//
// ## Metadata
// tag: type-conversion
builtin hmac : (v: A, k: A) => string
86 changes: 86 additions & 0 deletions stdlib/contrib/qxip/hash/hash.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ package hash

import (
"context"
_hmac "crypto/hmac"
_md5 "crypto/md5"
_sha1 "crypto/sha1"
_sha256 "crypto/sha256"
_b64 "encoding/base64"
"encoding/hex"
"github.com/cespare/xxhash/v2"
"strconv"
Expand Down Expand Up @@ -33,8 +37,12 @@ func makeFunction(name string, fn function) values.Function {

func init() {
runtime.RegisterPackageValue(pkgName, "sha256", makeFunction("sha256", sha256))
runtime.RegisterPackageValue(pkgName, "sha1", makeFunction("sha1", sha1))
runtime.RegisterPackageValue(pkgName, "xxhash64", makeFunction("xxhash64", xxhash64))
runtime.RegisterPackageValue(pkgName, "cityhash64", makeFunction("cityhash64", cityhash64))
runtime.RegisterPackageValue(pkgName, "md5", makeFunction("md5", md5))
runtime.RegisterPackageValue(pkgName, "b64", makeFunction("b64", b64))
runtime.RegisterPackageValue(pkgName, "hmac", makeFunction("hmac", hmac))
}

var errMissingArg = errors.Newf(codes.Invalid, "missing argument %q", conversionArg)
Expand All @@ -57,6 +65,59 @@ func sha256(args interpreter.Arguments) (values.Value, error) {
}
}

func sha1(args interpreter.Arguments) (values.Value, error) {
v, ok := args.Get(conversionArg)
if !ok {
return nil, errMissingArg
} else if v.IsNull() {
return values.Null, nil
}
switch v.Type().Nature() {
case semantic.String:
s := v.Str()
hash := _sha1.Sum([]byte(s))
str := hex.EncodeToString(hash[:])
return values.NewString(str), nil
default:
return nil, errors.Newf(codes.Invalid, "hash cannot convert %v to sha1", v.Type())
}
}

func md5(args interpreter.Arguments) (values.Value, error) {
v, ok := args.Get(conversionArg)
if !ok {
return nil, errMissingArg
} else if v.IsNull() {
return values.Null, nil
}
switch v.Type().Nature() {
case semantic.String:
s := v.Str()
hash := _md5.Sum([]byte(s))
str := hex.EncodeToString(hash[:])
return values.NewString(str), nil
default:
return nil, errors.Newf(codes.Invalid, "hash cannot convert %v to md5", v.Type())
}
}

func b64(args interpreter.Arguments) (values.Value, error) {
v, ok := args.Get(conversionArg)
if !ok {
return nil, errMissingArg
} else if v.IsNull() {
return values.Null, nil
}
switch v.Type().Nature() {
case semantic.String:
s := v.Str()
str := _b64.URLEncoding.EncodeToString([]byte(s))
return values.NewString(str), nil
default:
return nil, errors.Newf(codes.Invalid, "hash cannot convert %v to b64", v.Type())
}
}

func xxhash64(args interpreter.Arguments) (values.Value, error) {
v, ok := args.Get(conversionArg)
if !ok {
Expand Down Expand Up @@ -92,3 +153,28 @@ func cityhash64(args interpreter.Arguments) (values.Value, error) {
return nil, errors.Newf(codes.Invalid, "hash cannot convert %v to sha256", v.Type())
}
}

func hmac(args interpreter.Arguments) (values.Value, error) {
v, ok := args.Get(conversionArg)
if !ok {
return nil, errMissingArg
} else if v.IsNull() {
return values.Null, nil
}
k, kok := args.Get("k")
if !kok {
return nil, errMissingArg
} else if k.IsNull() {
return values.Null, nil
}
switch v.Type().Nature() {
case semantic.String:
key_for_sign := []byte(k.Str())
h := _hmac.New(_sha1.New, key_for_sign)
h.Write([]byte(v.Str()))
str := _b64.StdEncoding.EncodeToString(h.Sum(nil))
return values.NewString(str), nil
default:
return nil, errors.Newf(codes.Invalid, "hash cannot convert %v to hmac", v.Type())
}
}

0 comments on commit 1eba4ff

Please sign in to comment.