关于七牛qetag算法的一些记录

背景 今天做七牛相关接口开发的时候发现七牛的文件查询列表返回,有个hash字段,但是不知道是怎么进行计算的。后来查询到七牛的官方仓库 qetag.官方对这个算法的描述是这样的: qetag 是一个计算文件在七牛云存储上的 hash 值(也是文件下载时的 etag 值)的实用程序。 七牛的 hash/etag 算法是公开的。算法大体如下: 如果你能够确认文件 <= 4M,那么 hash = UrlsafeBase64([0x16, sha1(FileContent)])。也就是,文件的内容的sha1值(20个字节),前面加一个byte(值为0x16),构成 21 字节的二进制数据,然后对这 21 字节的数据做 urlsafe 的 base64 编码。 如果文件 > 4M,则 hash = UrlsafeBase64([0x96, sha1([sha1(Block1), sha1(Block2), …])]),其中 Block 是把文件内容切分为 4M 为单位的一个个块,也就是 BlockI = FileContent[I*4M:(I+1)*4M]。 为何需要公开 hash/etag 算法?这个和 “消重” 问题有关,详细见: https://developer.qiniu.com/kodo/kb/1365/how-to-avoid-the-users-to-upload-files-with-the-same-key http://segmentfault.com/q/1010000000315810 为何在 sha1 值前面加一个byte的标记位(0x16或0x96)? 0x16 = 22,而 2^22 = 4M。所以前面的 0x16 其实是文件按 4M 分块的意思。 0x96 = 0x80 | 0x16。其中的 0x80 表示这个文件是大文件(有多个分块),hash 值也经过了2重的 sha1 计算。 语言封装 C# 实现 基于官方仓库的csharp代码做了部分修改...

January 22, 2024 · 3 min · czyt

Golang 高级时间工具函数

本文为 https://medium.com/canopas/golang-date-time-utilities-part-2-b1192eb04842 文章的翻译。正文部分进行了部分调整。 背景介绍 在编程世界中,处理日期和时间是一项常见的任务,通常需要精确性和灵活性。 虽然 Go 编程语言的标准库提供了 time 软件包来处理与时间相关的操作,但在某些情况下,开发人员需要额外的实用程序来简化与时间相关的任务。 在本篇博文中,我们将探讨一组实用工具函数,它们是 time 程序包的封装,可为操作提供便利。如果您不了解 time程序包,请考虑在深入学习高级实用程序之前参考一下相关文档。 有关基本功能,请参阅您始终需要的时间实用功能。 🎯 那么,让我们深入探讨一下如何实现。 实现 1.获取月初 一个月的开始是许多日期相关计算的基本参考点。让我们创建一个函数,将日期作为输入,并根据系统时区返回相应月份的第一天: func StartOfMonth(date time.Time) time.Time { return time.Date(date.Year(), date.Month(), 1, 0, 0, 0, 0, date.Location()) } // function called StartOfMonth(time.Now()) // output 2024-01-01 00:00:00 +0530 IST 此函数将月日设置为 1,其他部分保持不变。 2.获取月末数据 相反,获取月末也同样重要。下面的函数返回给定月份最后一天的最后一秒: func EndOfMonth(date time.Time) time.Time { firstDayOfNextMonth := StartOfMonth(date).AddDate(0, 1, 0) return firstDayOfNextMonth.Add(-time.Second) } // function called EndOfMonth(time.Now()) // output 2024-01-31 23:59:59 +0530 IST 该函数利用之前定义的 StartOfMonth 函数查找下个月的第一天,然后减去一秒,得到当前月份的月底。...

January 18, 2024 · 4 min · czyt

如何获取一个Github或者gitlab用户的公钥

背景 今天无意在t上看到,然后找到这个帖子 https://stackoverflow.com/questions/16158158/what-is-the-public-url-for-the-github-public-keys How TO 获取 GitHub 可以通过下面链接 https://github.com/USER.keys https://github.com/USER.gpg 当然也可以通过github的api方式来获取 curl -i https://api.github.com/users/<username>/keys GitLab可以使用下面链接 https://gitlab.com/USER.keys https://gitlab.com/USER.gpg 使用 以github为例 curl https://github.com/<username>.keys | tee -a ~/.ssh/authorized_keys 添加完毕以后,对方就可以用ssh直接连接到你的电脑了。 这个帖子还举了bitbucket的例子 curl -i https://bitbucket.org/api/1.0/users/<accountname>/ssh-keys 延伸阅读 史上最全 SSH 暗黑技巧详解

January 17, 2024 · 1 min · czyt

Google Service Weaver中文文档[机翻]

本文为 Service Weaver 文档的机器翻译+细节微调。 Service Weaver是什么 ? Service Weaver 是一个用于编写、部署和管理分布式应用程序的编程框架。您可以在计算机上本地运行、测试和调试 Service Weaver 应用程序,然后使用单个命令将该应用程序部署到云。 $ go run . # Run locally. $ weaver ssh deploy weaver.toml # Run on multiple machines. $ weaver gke deploy weaver.toml # Run on Google Cloud. $ weaver kube deploy weaver.toml # Run on Kubernetes. Service Weaver 应用程序由许多组件组成。组件被表示为常规的 Go 接口,组件之间通过调用这些接口定义的方法进行交互。这使得编写 Service Weaver 应用程序变得容易。您不必编写任何网络或序列化代码;你只要写 Go 就可以了。 Service Weaver 还提供用于日志日志、指标、跟踪、路由、测试等的库。 您可以像运行单个命令一样轻松地部署 Service Weaver 应用程序。在幕后,Service Weaver 将沿着组件边界Profile您的二进制文件,从而允许不同的组件在不同的计算机上运行。 Service Weaver 将为您复制、自动缩放和共同定位这些分布式组件。它还将代表您管理所有网络详细信息,确保不同的组件可以相互通信,并且客户端可以与您的应用程序通信。...

January 12, 2024 · 37 min · czyt

一些使用go-fyne的笔记

界面交互 中文字体设置 查阅相关资料,有下面几种解决方案,下面来依次说明。 环境变量 可以通过指定 FYNE_FONT 环境变量来使用替代字体 使用字体bundle 安装fyne工具,使用下面的命令: go install fyne.io/fyne/v2/cmd/fyne@latest 准备好要使用的字体,我们这里使用miSans,使用下面命令 fyne bundle MiSans-Normal.ttf > bundle.go 然后创建一个theme package tinytheme import ( "fyne.io/fyne/v2" "fyne.io/fyne/v2/theme" "fyneHello/fontRes" "image/color" ) type ChineseTheme struct{} var _ fyne.Theme = (*ChineseTheme)(nil) func (m *ChineseTheme) Font(s fyne.TextStyle) fyne.Resource { return fontRes.ResourceMiSansTTF } func (*ChineseTheme) Color(n fyne.ThemeColorName, v fyne.ThemeVariant) color.Color { return theme.DefaultTheme().Color(n, v) } func (*ChineseTheme) Icon(n fyne.ThemeIconName) fyne.Resource { return theme.DefaultTheme().Icon(n) } func (*ChineseTheme) Size(n fyne....

January 11, 2024 · 11 min · czyt

使用go来编写graphql服务

本文为 文章 Go GraphQL Go!!! A beginner’s guide to GraphQL in Go using Ent. 的翻译。大部分使用机翻,部分内容作了相应调整。原文地址为 https://psj.codes/go-graphql-go 您是否想知道计算机和应用程序如何相互通信以获取信息?嗯,他们使用一种称为 API 的东西,它代表应用程序编程接口。 API 充当桥梁,允许不同的软件系统相互通信并交换数据。 在互联网的早期,构建 API 具有挑战性。开发人员必须以一种对每个使用它们的人都有意义的方式进行设计。这就像试图从调酒师那里点一杯饮料,而调酒师的菜单很复杂,有太多的选择。您通常会得到比您需要的更多或不够的信息,例如订购一杯简单的橙汁并收到整个水果篮!这给开发人员带来了挫败感并浪费了时间,他们必须筛选不必要的数据或发出多个请求才能获得他们想要的东西。想象一下,您必须向调酒师要一杯饮料,但您收到的不是简单的订单,而是完整的饮料目录!更糟糕的是,传统 API(称为 REST API)依赖大量端点。这些端点充当访问数据不同部分的特定路径。这就像一个迷宫,里面有无数扇门需要穿过。但随后,改变游戏规则的事情发生了。 Facebook 在 2012 年推出了 GraphQL,这是一种构建 API 的革命性方法,彻底扭转了局面。借助 GraphQL,开发人员终于告别了数据过度获取和数据获取不足的麻烦。快进到 2015 年,Facebook 开源了 GraphQL,并于 2018 年将 GraphQL 捐赠给了 Linux 基金会。 GraphQL 是一种 API 查询语言,或者有人可能会说它是开发 API 的新标准。 在本博客中,我们将探讨 GraphQL 如何应对传统 REST API 面临的挑战。我们还将踏上在 Go 中构建 GraphQL 服务器的实践之旅,为了使我们的开发过程更加令人兴奋和高效,我们将利用 Ent 的强大功能,这是一个专为 Go 设计的令人惊叹的实体库。 GraphQL 救世主 在简介中,我们提到了 RESTful API 的问题。让我们尝试理解它们并研究 GraphQL 如何解决它们。...

December 29, 2023 · 11 min · czyt

golang并发二三事

本文主要是鸟窝《深入理解go并发编程》中的读书速记以及一些并发库的使用例子集合 常用的并发库使用 sourcegraph conc waitgroup 创建一组协程并等待完成: 标准库 func main() { var wg sync.WaitGroup for i := 0; i < 10; i++ { wg.Add(1) go func() { defer wg.Done() // crashes on panic! doSomething() }() } wg.Wait() } conc func main() { var wg conc.WaitGroup for i := 0; i < 10; i++ { wg.Go(doSomething) } wg.Wait() } 下面是一个官网博客的例子: 写一个函数,给定用户的名字,通过网络获取姓氏 func fetchLastName(ctx context.Context, firstName string) (string, error) { req, err := http....

December 18, 2023 · 3 min · czyt

使用melody来创建正则表达式

melody是一款rust编写的编译输出为正则表达式的语言。Arch用户可以使用 paru -Syu melody 来安装,vscode和jetbrains系的IDE也有插件。 语法 下面是基于官方book的机翻语法。 量词 ... of - 用于表达特定数量的模式。相当于正则表达式 {5} (假设 5 of ... ) ... to ... of - 用于表示模式范围内的数量。相当于正则表达式 {5,9} (假设 5 to 9 of ... ) over ... of - 用于表达多个模式。相当于正则表达式 {6,} (假设 over 5 of ... ) some of - 用于表达 1 个或多个模式。相当于正则表达式 + any of - 用于表达 0 个或多个模式。相当于正则表达式 * option of - 用于表示模式的 0 或 1。相当于正则表达式 ? 所有量词前面都可以添加 lazy 以匹配最少数量的字符而不是最多的字符(贪婪)。相当于正则表达式 +? 、 *?...

December 15, 2023 · 2 min · czyt

使用uber cff进行并发编程

第一个项目 配置相关工具 先决条件 Go 1.18 或更新版本 带有 go.mod 文件的项目 大多数go项目应采取以下步骤建立 cff。 如果项目目录中还没有 “tools.go”,请在其中创建一个。您将在此指定开发时的依赖关系。 cat > tools.go <<EOF //go:build tools package tools // use your project's package name here EOF 确保使用与项目目录相同的软件包名称。 将 import _ "go.uber.org/cff/cmd/cff" 添加到 tools.go 中。 echo 'import _ "go.uber.org/cff/cmd/cff"' >> tools.go 运行 go mod tidy 获取最新版本的 cff,或运行 go get go.uber.org/cff@main 获取当前未发布的分支。 go mod tidy 将 cff CLI 安装到项目的 bin/ 子目录下。 GOBIN=$(pwd)/bin go install go.uber.org/cff/cmd/cff 请随意 gitignore 此目录。 echo '/bin' >> ....

December 14, 2023 · 8 min · czyt

使用uber-go的fx进行依赖注入

入门 下面是一个官方的例子: package main import ( "context" "fmt" "go.uber.org/fx" "io" "net" "net/http" "os" ) func main() { fx.New( fx.Provide( NewHTTPServer, NewEchoHandler, NewServeMux, ), fx.Invoke(func(srv *http.Server) {}), ).Run() } func NewHTTPServer(lc fx.Lifecycle, mux *http.ServeMux) *http.Server { srv := &http.Server{ Addr: ":8080", Handler: mux, } lc.Append(fx.Hook{ OnStart: func(ctx context.Context) error { ln, err := net.Listen("tcp", srv.Addr) if err != nil { return err } fmt.Println("Starting HTTP server at", srv.Addr) go srv.Serve(ln) return nil }, OnStop: func(ctx context....

December 13, 2023 · 5 min · czyt