Documentation ¶
Index ¶
- Constants
- func AesCbcDecrypt(cipherText, key, iv []byte) (plainText []byte)
- func AesCbcEncrypt(plainText, key, iv []byte) (cipherText []byte)
- func AesEcbDecrypt(cipherText, key []byte) (plainText []byte)
- func AesEcbEncrypt(plainText, key []byte) (cipherText []byte)
- func AppPath() string
- func ApproxEqualUnitNo(original, proposed string) bool
- func Catch(err *error)
- func DesEcbDecrypt(cipherText, key []byte) (plainText []byte)
- func DesEcbEncrypt(plainText, key []byte) (cipherText []byte)
- func DisableMockHTTPClient()
- func GetField(object interface{}, fieldName string) interface{}
- func MockConf()
- func MockHTTPClientError(err error)
- func MockHTTPClientRespBody(body string)
- func MockHTTPClientRespBodyFromFile(mockFile string)
- func MockStaticUnixMilli(t int64)
- func Must(err error)
- func NormalizeTrainNo(trainNo string) (results []string)
- func NormalizeUnitNo(unitNo string) string
- func PKCS7Padding(input []byte, blockSize int) (buf []byte)
- func PKCS7Unpadding(padded []byte) []byte
- func PrettyPrint(obj interface{})
- func ReadMockFile(mockFile string) (content []byte)
- func SetCookies(req *http.Request, cookies []*http.Cookie)
- func StructDecode(src interface{}, dest interface{}) error
- func UnixMilli(args ...time.Time) int64
- type AdapterConf
- type Duration
- type GenerationRule
- type GlobalConf
- type HTTPRequester
- type RequestConf
- type ScheduleConf
Examples ¶
Constants ¶
const (
ContentType = "application/json"
)
const (
// ISODate is the date layout defined in ISO 8601 or RFC 3339.
ISODate = "2006-01-02"
)
const (
RequestTimeout = 20 * time.Second
)
Variables ¶
This section is empty.
Functions ¶
func AesCbcDecrypt ¶
AesCbcDecrypt is the counterpart of AesCbcEncrypt; it decrypts the cipher text and strips the PKCS #7 padding bytes off the end of the plain text.
Example ¶
package main import ( "bytes" "fmt" "math/rand" "github.com/arnie97/emu-log/common" ) func main() { entropy := make([]byte, 42) rand.Read(entropy) key, iv, text := entropy[:16], entropy[16:32], entropy[32:] cipherText := common.AesCbcEncrypt(text, key, iv) fmt.Println(bytes.Compare(common.AesCbcDecrypt(cipherText, key, iv), text)) }
Output: 0
func AesCbcEncrypt ¶
AesCbcEncrypt encrypts the plain text with PKCS #7 padding, block chaining mode of operation, and a predefined initial vector.
Example ¶
package main import ( "fmt" "github.com/arnie97/emu-log/common" ) func main() { fmt.Println(common.AesCbcEncrypt( []byte("Arnie97"), []byte("$ecure*P@$$w0rd$"), []byte("initialVector128"), )) }
Output: [46 169 15 51 223 19 237 171 243 81 115 177 56 118 214 219]
func AesEcbDecrypt ¶
AesEcbDecrypt is the counterpart of AesEcbEncrypt; it decrypts the cipher text and strips the PKCS #7 padding bytes off the end of the plain text.
Example ¶
package main import ( "bytes" "fmt" "math/rand" "github.com/arnie97/emu-log/common" ) func main() { entropy := make([]byte, 100) rand.Read(entropy) key, text := entropy[:32], entropy[32:] cipherText := common.AesEcbEncrypt(text, key) fmt.Println(bytes.Compare(common.AesEcbDecrypt(cipherText, key), text)) }
Output: 0
func AesEcbEncrypt ¶
AesEcbEncrypt encrypts the plain text with PKCS #7 padding and electronic codebook mode of operation.
Example ¶
package main import ( "fmt" "github.com/arnie97/emu-log/common" ) func main() { fmt.Println(common.AesEcbEncrypt( []byte("Arnie97"), []byte("$ecure*P@$$w0rd$"), )) }
Output: [65 104 5 194 136 199 209 10 240 48 109 82 11 205 74 176]
func AppPath ¶
func AppPath() string
AppPath returns the relative path for the directory in which the binary executable of this application resides.
func ApproxEqualUnitNo ¶
ApproxEqualUnitNo compares whether the proposed unit number is approximately the same as the original one.
Example ¶
package main import ( "fmt" "github.com/arnie97/emu-log/common" ) func main() { fmt.Println( common.ApproxEqualUnitNo("CRH380B3626", "CHR380B3626"), common.ApproxEqualUnitNo("CR400BF5033", "5033"), common.ApproxEqualUnitNo("CRH5A5124", "CRH5A15124"), common.ApproxEqualUnitNo("CRH2E2462", "CR8+8-0@459"), common.ApproxEqualUnitNo("CRH2A2002", "CRH6A4002"), common.ApproxEqualUnitNo("CR", "CR"), common.ApproxEqualUnitNo("CRH6C2145", ""), common.ApproxEqualUnitNo("", "CRH2C2150"), ) }
Output: true true true true false true false true
func Catch ¶
func Catch(err *error)
Catch captures a possible panic and return it as an error.
Example ¶
package main import ( "fmt" "github.com/arnie97/emu-log/common" ) func main() { fmt.Println(panicFree()) } func panicFree() (err error) { defer common.Catch(&err) panic("BOOM!") }
Output: panic: BOOM!
func DesEcbDecrypt ¶
DesEcbDecrypt is the counterpart of DesEcbEncrypt; it decrypts the cipher text and strips the PKCS #7 padding bytes off the end of the plain text.
Example ¶
package main import ( "bytes" "fmt" "math/rand" "github.com/arnie97/emu-log/common" ) func main() { entropy := make([]byte, 100) rand.Read(entropy) key, text := entropy[:8], entropy[8:] cipherText := common.DesEcbEncrypt(text, key) fmt.Println(bytes.Compare(common.DesEcbDecrypt(cipherText, key), text)) }
Output: 0
func DesEcbEncrypt ¶
DesEcbEncrypt encrypts the plain text with PKCS #7 padding and electronic codebook mode of operation.
Example ¶
package main import ( "fmt" "github.com/arnie97/emu-log/common" ) func main() { fmt.Println(common.DesEcbEncrypt( []byte("Arnie97"), []byte("P@$$w0rd"), )) }
Output: [175 255 31 191 150 239 19 134]
func DisableMockHTTPClient ¶
func DisableMockHTTPClient()
func GetField ¶
func GetField(object interface{}, fieldName string) interface{}
GetField takes an arbitary structure, and uses reflection to retrieve the field with specified name from it. Panics if the field does not exist.
Example ¶
package main import ( "fmt" "github.com/arnie97/emu-log/common" ) func main() { station := struct { Pinyin, Telegraphy string TMIS int }{"HGT", "HTT", 53144} fmt.Println( common.GetField(station, "Pinyin"), common.GetField(station, "Telegraphy"), common.GetField(station, "TMIS"), ) defer func() { if recover() == nil { fmt.Println("panic expected here!") } }() common.GetField(station, "Nonexistent") }
Output: HGT HTT 53144
func MockHTTPClientError ¶
func MockHTTPClientError(err error)
func MockHTTPClientRespBody ¶
func MockHTTPClientRespBody(body string)
func MockHTTPClientRespBodyFromFile ¶
func MockHTTPClientRespBodyFromFile(mockFile string)
Example ¶
package main import ( "bufio" "bytes" "fmt" "github.com/arnie97/emu-log/common" ) func main() { common.MockHTTPClientRespBodyFromFile("../http_client_mock_test.go") x := common.HTTPClient() a, e := x.Do(nil) b, f := x.Get("") c, g := x.Post("", "", bytes.NewReader(nil)) d, h := x.PostForm("", nil) fmt.Println("same resp:", a == b || b == c || c == d) body, i := bufio.NewReader(d.Body).ReadString('\n') j := d.Body.Close() fmt.Println("no errors:", isAllNil(e, f, g, h, i, j)) fmt.Print("resp body: ", body) common.MockHTTPClientError(fmt.Errorf("my sample error")) k, m := common.HTTPClient().Do(nil) fmt.Printf("err mock: %v, %v", k.Body, m) } func isAllNil(values ...interface{}) bool { for _, v := range values { if v != nil { return false } } return true }
Output: same resp: false no errors: true resp body: package common_test err mock: <nil>, my sample error
func MockStaticUnixMilli ¶
func MockStaticUnixMilli(t int64)
Example ¶
package main import ( "fmt" "math/rand" "github.com/arnie97/emu-log/common" ) func main() { mockTime := int64(rand.Uint32()) common.MockStaticUnixMilli(mockTime) fmt.Println(common.UnixMilli() == mockTime) }
Output: true
func Must ¶
func Must(err error)
Must prints the error message and exit immediately if error is not nil.
func NormalizeTrainNo ¶
NormalizeTrainNo converts possibly abbreviated train number pairs to an array of full qualified train number strings.
Example ¶
package main import ( "fmt" "github.com/arnie97/emu-log/common" ) func main() { fmt.Println( common.NormalizeTrainNo("C1040/37/40"), common.NormalizeTrainNo("G1040/1"), common.NormalizeTrainNo("D1040"), common.NormalizeTrainNo("1040/1"), common.NormalizeTrainNo("CRH6"), ) }
Output: [C1040 C1037 C1040] [G1040 G1041] [D1040] [] []
func NormalizeUnitNo ¶
Example ¶
package main import ( "fmt" "github.com/arnie97/emu-log/common" ) func main() { for _, unitNo := range []string{ "CRH_6-002A", "CRH5A1-5028", "CR200J2-4001", "CHR380B-3770", "CRH380DV-1503", "CRH380D-V1-1504", "CR400BFB-1-5097 ", " CR400AFBZ2-2249 ", } { fmt.Println(common.NormalizeUnitNo(unitNo)) } }
Output: CRH6002A CRH5A5028 CR200J4001 CRH380B3770 CRH380D1503 CRH380D1504 CR400BFB5097 CR400AFBZ2249
func PKCS7Padding ¶
PKCS7Padding pads the input octet vector to a multiple of blockSize octets with the scheme defined in RFC 2315.
Example ¶
package main import ( "fmt" "github.com/arnie97/emu-log/common" ) func main() { fmt.Println(common.PKCS7Padding([]byte("abcdefgh"), 8)) fmt.Println(common.PKCS7Padding([]byte("abcdefg"), 16)) fmt.Println(common.PKCS7Padding([]byte("abcdef"), 256)) }
Output: [97 98 99 100 101 102 103 104 8 8 8 8 8 8 8 8] [97 98 99 100 101 102 103 9 9 9 9 9 9 9 9 9] []
func PKCS7Unpadding ¶
PKCS7Unpadding removes the padded bytes from the decrypted text according to the last decrypted byte to recover the original payload.
Example ¶
package main import ( "fmt" "github.com/arnie97/emu-log/common" ) func main() { fmt.Println(common.PKCS7Unpadding([]byte{})) fmt.Println(common.PKCS7Unpadding([]byte{1, 2, 3, 5, 5, 5, 5, 5})) }
Output: [] [1 2 3]
func PrettyPrint ¶
func PrettyPrint(obj interface{})
PrettyPrint displays a nested structure in human readable JSON format.
Example ¶
package main import ( "github.com/arnie97/emu-log/common" ) func main() { common.PrettyPrint(map[string]interface{}{ "CIT380A": "CRH2C-2150", "CR200J": nil, "CR400AF": []string{"0207", "0208"}, "CR400BF": []string{"0503", "0507", "0305"}, "CRH6A": 4002, }) }
Output: { "CIT380A": "CRH2C-2150", "CR200J": null, "CR400AF": [ "0207", "0208" ], "CR400BF": [ "0503", "0507", "0305" ], "CRH6A": 4002 }
func ReadMockFile ¶
func StructDecode ¶
func StructDecode(src interface{}, dest interface{}) error
StructDecode takes a source structure, and uses reflection to translate it to the destination structure. Typically used to convert native Go structures to map[string]interface{}, and vice versa.
Example ¶
package main import ( "fmt" "github.com/arnie97/emu-log/common" ) func main() { var dest struct { Field []int64 `json:"root"` } testCases := []interface{}{ func() {}, map[string]interface{}{"root": "123"}, map[string]interface{}{"root": []float32{1, 2, 3}}, } for _, testCase := range testCases { err := common.StructDecode(testCase, &dest) fmt.Printf("%+v %v\n", dest, err != nil) } }
Output: {Field:[]} true {Field:[]} true {Field:[1 2 3]} false
func UnixMilli ¶
UnixMilli backports time.UnixMilli() from Go 1.17 and later versions.
Example ¶
package main import ( "fmt" "time" "github.com/arnie97/emu-log/common" ) func main() { // The doomsday of gophers! t, err := time.Parse(time.RFC1123, "Sat, 12 Apr 2262 07:47:16 CST") fmt.Println(common.UnixMilli(t), err) fmt.Println(common.UnixMilli(time.Now()) == common.UnixMilli()) defer func() { fmt.Println(recover() != nil) }() common.UnixMilli(time.Now(), time.Now()) }
Output: 9223372036000 <nil> true true
Types ¶
type AdapterConf ¶
type AdapterConf struct { Request *RequestConf `toml:"request,omitempty"` SearchSpace []GenerationRule `toml:"search,omitempty"` }
func (AdapterConf) EmitSerials ¶
func (a AdapterConf) EmitSerials(serials chan<- string)
type Duration ¶
Duration is a TOML wrapper type for time.Duration. https://github.com/golang/go/issues/16039
func (Duration) MarshalText ¶
MarshalText formats a Duration value into a TOML string.
func (*Duration) UnmarshalText ¶
UnmarshalText parses a TOML string into a Duration value.
type GenerationRule ¶
type GenerationRule struct { Format string `toml:"format,omitempty"` Min *int `toml:"min,omitempty"` Max *int `toml:"max,omitempty"` Step *int `toml:"step,omitempty"` }
func (*GenerationRule) EmitSerials ¶
func (rule *GenerationRule) EmitSerials(serials chan<- string)
type GlobalConf ¶
type GlobalConf struct { Request *RequestConf `toml:"request,omitempty"` Schedule ScheduleConf `toml:"schedule,omitempty"` Adapters map[string]AdapterConf `toml:"adapters,omitempty"` }
func Conf ¶
func Conf() *GlobalConf
Conf loads configuration from a TOML file on the filesystem when the function is being called for the first time.
Example ¶
package main import ( "fmt" "github.com/arnie97/emu-log/common" ) func main() { common.MockConf() fmt.Println(int64(common.Conf().Request.Interval)) common.PrettyPrint(common.Conf().Request.Interval) serials := make(chan string) for _, a := range common.Conf().Adapters { if len(a.SearchSpace) > 0 { go a.EmitSerials(serials) } } for s := range serials { fmt.Println(s) } }
Output: 2460 "2.46µs" CRH5-001A CRH3-002C CRH3-004C CRH3-009C CRH2-001A CRH2-002A CRH2-003A
type HTTPRequester ¶
type HTTPRequester interface { Do(*http.Request) (*http.Response, error) Get(url string) (*http.Response, error) Post(url, contentType string, body io.Reader) (*http.Response, error) PostForm(url string, data url.Values) (*http.Response, error) }
func HTTPClient ¶
func HTTPClient(roundTripper ...http.RoundTripper) HTTPRequester
Example ¶
package main import ( "encoding/json" "fmt" "io/ioutil" "net/http" "github.com/arnie97/emu-log/common" ) func main() { common.DisableMockHTTPClient() common.MockConf() x := common.HTTPClient() y := common.HTTPClient(http.DefaultTransport) fmt.Println("x == y: ", x == y) const api = "https://httpbin.org/anything" req, _ := http.NewRequest(http.MethodPut, api, nil) common.SetCookies(req, nil) common.SetCookies(req, []*http.Cookie{ {Name: "model", Value: "CRH6A"}, {Name: "serial", Value: "4002"}, }) cookies := req.Header.Get("cookie") fmt.Println("cookies: ", cookies) resp, err := x.Do(req) fmt.Println("get err: ", err) body, err := ioutil.ReadAll(resp.Body) fmt.Println("read err:", err) s := struct { Headers struct { Cookies string `json:"cookie"` UserAgent string `json:"user-agent"` } `json:"headers"` }{} err = json.Unmarshal(body, &s) fmt.Println("load err:", err) fmt.Println("ua equal:", s.Headers.UserAgent == "Mozilla/5.0") fmt.Println("cookies: ", s.Headers.Cookies == cookies) }
Output: x == y: false cookies: model=CRH6A; serial=4002 get err: <nil> read err: <nil> load err: <nil> ua equal: true cookies: true