mirror of
https://github.com/duke-git/lancet.git
synced 2026-03-01 00:35:28 +08:00
Compare commits
5 Commits
a254ebdc8e
...
921f218ef7
| Author | SHA1 | Date | |
|---|---|---|---|
| 921f218ef7 | |||
| 0a2cc9c928 | |||
| ed93aae970 | |||
| 1671f7856a | |||
| 1008dd4956 |
@@ -1,51 +1,51 @@
|
|||||||
-----BEGIN rsa private key-----
|
-----BEGIN rsa private key-----
|
||||||
MIIJJwIBAAKCAgEAs+rfCwwvBb9JplwDAaNtpEPCm1DoS8PkqzwSSxfA7JHSMYdY
|
MIIJKgIBAAKCAgEAsZoYOi7lxZ3zk4zTa/nvlQzPeXNBthaUpAJmC1b2/ldmglZ8
|
||||||
UMq92vbSqEKomNgyksaGIiqDHop+9pHjYI1Aftd6mbZJwRtQxo+5eYGh88FzPqem
|
ARGoVv45VCjG1yKO47SiN8ijcA///o/EawGZ8mJHv8WsPUBxzUF2OQHSZ/kHlbi1
|
||||||
mNubZk7SxGq0MEz1XmZ9viQyp3GxAJjeSdAG9GRdstNcczSy9Ij9YGJ8ehLhL/pn
|
vZsbGXLcM9siBU79uqudbyqUm/9OkgnTPCUUzOlaFtKGeyoDM4TBAX7ec8G8LWBd
|
||||||
g4ZsLUtwDbYsilJDx28qDX/jJ/nbopaHWk2XTSu8KK3zXBjppTU4uKKicOswaJ6k
|
BAgNAaK/vP+iXuPHxLdKNMDDel67nLNYJ30KC/fUbwHixn5yQLx4zVLF+rv3pUbQ
|
||||||
fk9J6ItkQ15uS+z2eHsxpa8K++gIt2swJkiERlqUzwiC75w92JH1nQPXqEqaaEx0
|
uTeEvS+N19Cg1/+5/xzGK+YYdO1ZH4qgubNBu9C90wH0FhIuDDfswh8liZbjHcXs
|
||||||
izdHUmFF33cgGb6gw5tJePzOmYs8KLJcOhfJQcqjW4MjCfnaw4tB/cpi3zYKzDoC
|
J82QPdaxjbz1bSb8OToackMMocvJVI9ToxSBdGvGoBk1mnLJRSab6nOD56+iRoGJ
|
||||||
7mzwitrkBO1MG11luzR1m9uMfWczL2hK2zMHI51vayC1d1T0gc56vS/SAdicl5Oq
|
my6GTpD2I1ie1PHV1Y2TIjUESnxjgPigaYA5i/MkXlD/1CtrDW6hsc0/WgCSD7ZG
|
||||||
cD6oc6Dmym3rguF/pauTIOrvGtipeYk/Mbb4qj2CI33QFTZc3G55yHVB6vDWIpMS
|
jNTduUwdwmd2es1XIqnamht+QJE1JTbBFLd9r5zXQY/5W5nRQHBmWP5fVHy7a/wm
|
||||||
WF60HHHqv7Ens4MIPIev0WS893vsNscg4Ph3QxXDNjOc3kEK17TnDGXmL7C+Ykfq
|
F9N2ZpI/DYMarCRIVBsiMdsE62mq63haB6ywjkVk+78TXtmXTTE8ts6XImt+m+0R
|
||||||
9brm32IrOMZ4KR3NJ+aO83yLewPoQAy8QCC32b1O3c1nAgSY9sIwJV8ikAdNDBhL
|
Y4lAd+UfHvyOe3dH2y5nGSHG4C8CXB264YdApZZjjvVZy5K3lsmmBB+4Kje1Rux3
|
||||||
nkXFrYE2ZFl/Kl5HXd0LCz/BQu3Ey0RsZfXIpD7KUcdNq3QRloTATntE9U0CAwEA
|
6F76qEOvjZ2QvpJDTXSXOk1POu6aZc8N+XRuvG7hmEPdF3xD68VPSZ5/gfcCAwEA
|
||||||
AQKCAgBebqKPC+AKZjJj7NtvGrZLh303RCoIylLVRXxciaUrBgaLFHzYOvGXYgGD
|
AQKCAgBNUUto0Q/g12G6A53rLPT7S4drVRzvW6c8O3sXRrXihkQvS91STdCehrCI
|
||||||
aylOv/sbarOwbxvPBeZJyJzNapY1fSfOUg04G/wzm/A/xDia1iiE9D3O8UUJV8ns
|
jfP6pqXURcg1Rti4KY8F0Kru9tSBa/3WZAUW6V5hwDTqnntuHkEKEk60i7jhfFqX
|
||||||
ag0VZO9MkwLgr+MeW+AJbjMODu/3ik5bs/BMT5a2HsjOtCKdeBdVtVprgDx7MaMo
|
DLgj3X6ibKHuSnhF7YDUHQjj7zS9/Hzm4KIBLooUPKAVuZi4hkgY7RGxdpvK8YJN
|
||||||
rzuFhlQo80HhQAScUNpk5hk43ozRZmkl+NdIuZK4scyJrGMSXX9VCh9QZJFoSvFf
|
knCqpLlMT4szqhOvy1wb3QvsrQfZq/vEk+qZBWVR/3sL0BQ2kuw9/LVTXPMhtXkn
|
||||||
IstFcqSS7CZMzik3urwIeWwWS+2Rd62vVMpUtW8IouOFfCTPIgkVQTvSbjszE/c2
|
0kCjqEXd5TX02IgfJ1EcZSqRjZN5Y2ewW/JaRXHcieA9pneeDZ00Ufz8WwaHlVbY
|
||||||
qTHiEVoUEQdpR1ew45G50pPxsdZhnoKY7SskyvmMNQmG0fIIM/wozAU2NQhJ13PC
|
4MFr0oQNmdj3k28FZQVyFa+QmJW+UgKqvkCaenDcAMFvMILpdBwReZH6H5ZYBaEt
|
||||||
duUPTEr2tPhuiHH7Rbjh0J7dEDQEacW+TKyzOaY88CDS5dpe1TBFuRlO7HjfK1r6
|
lYSQS/UVpeonrUTJmfroo48bC8aNB9ILTx80oeG7Uh50hhS+WL8yED1wlwXhCE6X
|
||||||
Jc6xiR00Waylp5ct8aOgO4q5VAwL9PzRgDrUZhfQmLPaLkxybEuJ6Jo5qIloPXmD
|
fMCY8C9wWfbOmuiZPJhKQOa2R46Gv09mKPjCw2l+tbM/Mg6GnakEW33GeS7V8hBA
|
||||||
Yyso1t43VH+IqmgU+eNNlq8d5sphzBXj+glSLtT+B2kP27Raz2VetZi70gKf6TPC
|
DUSETJSBuI9xJDXp4nseVK/B9SQVsJhiHxEq6DIG6WFNvTVkaHuZ6J58HdhSRXCU
|
||||||
QdoeUduzph+VSeJgfRa9slBOrTz3p2YNqZggBM51VA9jITCa8B3kiazgA4ggXMRq
|
FeItZNXNqXh5LaOV7DeAe0kHQ3LZ+LcX75JI20GDuL1rSTFKdz0aDkla2sFn1w7J
|
||||||
z4+++ae38rCQx8TVeMt6pqQ1aA8eFrKI8GoqEe+Co9og/yYZgQKCAQEA2vwKpje2
|
tIJ2sJOYwJZ/v93Lj5wCuVaKqlMq6oMQ8RTCB1CBZHhG2bkdcQKCAQEA51yhKsri
|
||||||
5VzaqOFl7aktz8eAkn3YuzfacKSESdXvv7ardBQIRaAAHZ8eMW1dfcVBi7BiE6Ti
|
SM5SEVn8mJYK+vsBh/WVgzJ9Cxuabi+h9D0/bGgsAvjMCPa/07h7SPDdBXhPmn1x
|
||||||
SCmll/NT91udR4i0bvjinDBZJCgqo6AiiIKp53yUNuyAWFI08rVDXn1BXaete9UL
|
P0cHkvjZt1zBMGcMw84jo7I+m5pAN6DZygIXakJZh+aBMR8M1L26/00anKj+IZY0
|
||||||
hBo8BCwQfV4VxyzYJVwl6Px/RrAB44Cu89ZHwB/6i+Wss97QmEgnOrqcsyZO6Qew
|
t2/8fJzfoNjMCoEk/Z9dpgOvssPs5cY0sxKVfp1uTubj5JbiUEsC1QV3iuAunodR
|
||||||
WitvxBuksz4oPGbJqV58tVPC+I4KKALplp76Tt1N1rm6yF+JMu59g/d1+yqua8A5
|
e/+IqNNaf/iu4bQKzkyVQltQfuocawKieBMcw+46mwZ+70oBHKUWWOvvzC7iAwVi
|
||||||
ON9bRPU2aA1Pb0Ya8+MqigbeGGpaqkJF2OMBcar2MbVVbNq5eUu7Zh4XqqGvDIN4
|
2GoRkND0hX4MBH4Zx0FOJnO16R6kRo/lmBv+2YtXHzG76KGfW9lEoHmNK33fL5Q5
|
||||||
nL7eXHL+axeIsQKCAQEA0lRPCK3tB8rxivJ+NIIgsP7lIMUG+LecZa5z7BZITamP
|
Z5u1z6lnXP6BzwKCAQEAxIPdxyY0z/H5DadbYqiA5ZhDB/UXbhyKikQ0UJ+ChRko
|
||||||
yghkSnCyR1wD7RPHCVUUYXtW9/7inGck3KhXzPERBdbLTYtI6gVYkbdGX2bnIQRE
|
5V3XLpqsJFW75BSePAHWLj0r9mGezi/ELeMpLQhE+hMZ2byx1LO2EbNKPS9it7Bh
|
||||||
GThyYqyxcoBdfwOXVuixOIAMYQBY1K/MyEgSH4XgM5q/OhN6FCutnBnifR9rTrUO
|
lIB/FTgv4dqLeVMP8Y3QiTgqQB/y4s7tu135H/UWqWm711LI3b/1igg/uiwMZ/Ot
|
||||||
4bzIM3e5CCSuuwY8/n9lPyzOpJwkxsXT8K6nS0Q1kZqbFT4YSAQhVzRHkYU/cFy2
|
CIWAllPmjPTNsjguC8W68Na7x2RLX2WeS+psOqK1M5l2+xJlIcVqm1zYFnBDWaPb
|
||||||
AtbCOuflek7d7gv4bGi2e/KkKyVOZJYP3i7eOwh6+xAe8f+QDkOzWGNunfe0ggIQ
|
cvfTuzCmcreWJ3c7c7mGCDcqBSAjqPkkMGD0OvDXTVIsLD6D3B+8xg2m69mQNU7W
|
||||||
78jnSENZRU8zExLDgXowIcfrF2iNVrGTFaz4PBBdXQKCAQAut0gaT5Zv9dAb6QHS
|
ej+809qebJQSVoSN6iF7DKyYWr/6o9/csL/m2ZLPWQKCAQEAybqbkEtcaKz1I8n5
|
||||||
op3ITroqBjjfL7ok/6PNEJu13WVUPRXKrKh5qUFKsBcaxqMGBtnVcP5pAKF3+gv2
|
lDXnlxT7Lcf1OHLyUpgb3A1OQj6RKX3fOiwjA4HamsmVPXE+1gEkL4lHECxnrz+p
|
||||||
oA+8e/hqGCRXx6Sspvj5sSbM0nsmjBgeY3O548ex42N82+G+9g93dGqhgus8xJ27
|
3dZTYFfJ6oS30IifTF9/tMFchGW0cuMtW3Chnun67xgLj4V0Obqj8zcb+gH7/c9u
|
||||||
8P9aX0G5LqBTxNHuJYwxmXk5QYRLA0dy4stmD+mWIwZja/4T5d89rUs84TlVr8QC
|
sbm2l0YpsbaeGh3GubFZwrNCygzfKoosX0G03WCuLeJpssHUjNOR8on8g4i4aLP4
|
||||||
DQeOYyswO50FHdphJgQapwxn+oBRpLp/TV4AcwkU2XXjWj5MF73f9MEAVf3lhx5V
|
ifKU0ZmBfoWJ81TZZ//LDYc7kETh5Pi4Qum0DgLR218akCgQa1FJoea1XAuIC2QW
|
||||||
Mkm45k7HqrWffnmQ4dd3rO2zqDHdqugckJ+pujuJGdPfpBnOZ/GtDLsFTV6ogEuw
|
gLr50YT+Bx2q/Z4QtBYSmK/pOerXGGoFad6cgGdEIvrbeqzhaVWUH9E3CF7ddRa5
|
||||||
UvPxAoIBAE6/RAvy2nD1ebPVEI1mPwkllfHL8s1CKWskgsBco1t4ZZ51v97jDMyM
|
WH1VQwKCAQEAvl479tNFL/hpWte4CH/RthjlPo0oMGwHrV/bCgsrxkIUQvXAIY6G
|
||||||
1ed4ZSfIU+YfgLM/GecG8xUubhkMFJyEDAAPaxA7SircXJuxck25RCnRKXpqP9Gn
|
mgBPruhmTR0+Xba2osv4qibNteIsHkq3f0YHsc1AvBuHkegMT+9agzWjoddExMqU
|
||||||
39mDJbFjU57cykWzFI8k9t3xpd9ph0Sq5ne+/RD6PXjZdCP2lH2Wamj3/ljOtVco
|
YAd1O4fCly7ZSESXcV1BzoPE+tBTKKklVeJurG2u1lpBw4CwM2q+bek5w1qIsZf/
|
||||||
LMdXEZUTa3vYsdGNqHNHdA+DxJz4f7nxEalFY1/rM/RrXXRNWDAgdgDgGT5mvlMp
|
bKctqKsRuCfJK8vpRoQbHAP17/bc94RtYtoUz64HOErlNjIfxsTkCa9ZRCtd+iVr
|
||||||
ngvXLX6hQdlsQizpPc2JJY3BLHEbvrerFHr0fSHqFQa9y5eXO10FmwO7y2QR2yWI
|
6Q99ryeq+TVM6SJ/W03CHcuUSiVyErMC7w1ea1H4LMK1/Wp2PF2bfHit/ulFxDkx
|
||||||
/o1glBQxBD5RlGJiQbC4sWIHLbWHRv0CggEAXfJYZ+HfUHAsP/QTOgHmlZETcb/s
|
ZV+f0B5C1/+tEx8TzD3T0PJo+PQ97qFwqQKCAQEAkVYt7fQgU0LA1kktM/qQRKK0
|
||||||
giZ/b2JUsvcyc+i7Rt6XLZr6ScHhV+bL1iaxy6QNUeSMOCPPhlsPfsjlW13MIBpg
|
2nyw9OpRiAmMeNZnTf4Gs7sBOJOifyfQzxweZ7FLnTJL3A9Mgw8sQtGSP3nGyaVb
|
||||||
Ux/lOgpb3UC6vEf+uJTRygiTwji65sitFdKW7vt1PBgBHnZ9ZmC2EShx0+E4QV0S
|
eeS62XdnbS6RVj9wbeegng205N4+Fowxmm27DeaNdfHJdAvKf7Qm/F3IC2dSQyPq
|
||||||
MDwptdewcKHYg5y4r86uER5XhZIJ1F+M0tKMVpzqGFQeCegRY6+S11Vdw5G28iOS
|
DtTDExCSq21BQpGjkKuo8YzDX9zZWkHtFUKitKf3o9k+vPvhHxfsP+dqpmyGP00S
|
||||||
4+r+xCRSPD4TVUJpxxnNERlzqjbS27C2AvkHs/J6tChhYndmrT/oLXd68ki2cphg
|
XuBmSwDUiCZ6nLyGnV42HTH6BvsMYrlXsDcQC311Dsow12nSjY4cJLdmQaAZntbD
|
||||||
ryKTB6TGP/iW6xODGxPefJYyxr4dTNOJeqdXTAgG9Sze5BH4/ku/ouzqZQ==
|
o0TDI4pZONqPOr/65emUHuIZ3mryt9XFO02rf4MU2WTpdYh0gBZm0ggw5lmO+g==
|
||||||
-----END rsa private key-----
|
-----END rsa private key-----
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
-----BEGIN rsa public key-----
|
-----BEGIN rsa public key-----
|
||||||
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAs+rfCwwvBb9JplwDAaNt
|
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsZoYOi7lxZ3zk4zTa/nv
|
||||||
pEPCm1DoS8PkqzwSSxfA7JHSMYdYUMq92vbSqEKomNgyksaGIiqDHop+9pHjYI1A
|
lQzPeXNBthaUpAJmC1b2/ldmglZ8ARGoVv45VCjG1yKO47SiN8ijcA///o/EawGZ
|
||||||
ftd6mbZJwRtQxo+5eYGh88FzPqemmNubZk7SxGq0MEz1XmZ9viQyp3GxAJjeSdAG
|
8mJHv8WsPUBxzUF2OQHSZ/kHlbi1vZsbGXLcM9siBU79uqudbyqUm/9OkgnTPCUU
|
||||||
9GRdstNcczSy9Ij9YGJ8ehLhL/png4ZsLUtwDbYsilJDx28qDX/jJ/nbopaHWk2X
|
zOlaFtKGeyoDM4TBAX7ec8G8LWBdBAgNAaK/vP+iXuPHxLdKNMDDel67nLNYJ30K
|
||||||
TSu8KK3zXBjppTU4uKKicOswaJ6kfk9J6ItkQ15uS+z2eHsxpa8K++gIt2swJkiE
|
C/fUbwHixn5yQLx4zVLF+rv3pUbQuTeEvS+N19Cg1/+5/xzGK+YYdO1ZH4qgubNB
|
||||||
RlqUzwiC75w92JH1nQPXqEqaaEx0izdHUmFF33cgGb6gw5tJePzOmYs8KLJcOhfJ
|
u9C90wH0FhIuDDfswh8liZbjHcXsJ82QPdaxjbz1bSb8OToackMMocvJVI9ToxSB
|
||||||
QcqjW4MjCfnaw4tB/cpi3zYKzDoC7mzwitrkBO1MG11luzR1m9uMfWczL2hK2zMH
|
dGvGoBk1mnLJRSab6nOD56+iRoGJmy6GTpD2I1ie1PHV1Y2TIjUESnxjgPigaYA5
|
||||||
I51vayC1d1T0gc56vS/SAdicl5OqcD6oc6Dmym3rguF/pauTIOrvGtipeYk/Mbb4
|
i/MkXlD/1CtrDW6hsc0/WgCSD7ZGjNTduUwdwmd2es1XIqnamht+QJE1JTbBFLd9
|
||||||
qj2CI33QFTZc3G55yHVB6vDWIpMSWF60HHHqv7Ens4MIPIev0WS893vsNscg4Ph3
|
r5zXQY/5W5nRQHBmWP5fVHy7a/wmF9N2ZpI/DYMarCRIVBsiMdsE62mq63haB6yw
|
||||||
QxXDNjOc3kEK17TnDGXmL7C+Ykfq9brm32IrOMZ4KR3NJ+aO83yLewPoQAy8QCC3
|
jkVk+78TXtmXTTE8ts6XImt+m+0RY4lAd+UfHvyOe3dH2y5nGSHG4C8CXB264YdA
|
||||||
2b1O3c1nAgSY9sIwJV8ikAdNDBhLnkXFrYE2ZFl/Kl5HXd0LCz/BQu3Ey0RsZfXI
|
pZZjjvVZy5K3lsmmBB+4Kje1Rux36F76qEOvjZ2QvpJDTXSXOk1POu6aZc8N+XRu
|
||||||
pD7KUcdNq3QRloTATntE9U0CAwEAAQ==
|
vG7hmEPdF3xD68VPSZ5/gfcCAwEAAQ==
|
||||||
-----END rsa public key-----
|
-----END rsa public key-----
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ import (
|
|||||||
- [ReadFile](#ReadFile)
|
- [ReadFile](#ReadFile)
|
||||||
- [ChunkRead](#ChunkRead)
|
- [ChunkRead](#ChunkRead)
|
||||||
- [ParallelChunkRead](#ParallelChunkRead)
|
- [ParallelChunkRead](#ParallelChunkRead)
|
||||||
|
- [GetExeOrDllVersion](#GetExeOrDllVersion)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
@@ -1076,4 +1077,34 @@ func main() {
|
|||||||
// Jim,21,male
|
// Jim,21,male
|
||||||
// 2
|
// 2
|
||||||
}
|
}
|
||||||
|
```
|
||||||
|
### <span id="GetExeOrDllVersion">GetExeOrDllVersion</span>
|
||||||
|
|
||||||
|
<p>返回exe,dll文件版本号(仅Window平台).</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func GetExeOrDllVersion(filePath string) (string, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:<span style="float:right;display:inline-block;">[运行](todo)</span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/fileutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
v, err := fileutil.GetExeOrDllVersion(`C:\Program Files\Tencent\WeChat\WeChat.exe`)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println(v)
|
||||||
|
// Output:
|
||||||
|
// 3.9.10.19
|
||||||
|
}
|
||||||
```
|
```
|
||||||
@@ -40,6 +40,7 @@ import (
|
|||||||
- [RandStringSlice](#RandStringSlice)
|
- [RandStringSlice](#RandStringSlice)
|
||||||
- [RandBool](#RandBool)
|
- [RandBool](#RandBool)
|
||||||
- [RandBoolSlice](#RandBoolSlice)
|
- [RandBoolSlice](#RandBoolSlice)
|
||||||
|
- [RandNumberOfLength](#RandNumberOfLength)
|
||||||
|
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
@@ -522,4 +523,29 @@ func main() {
|
|||||||
result := random.RandBoolSlice(2)
|
result := random.RandBoolSlice(2)
|
||||||
fmt.Println(result) // [true false] (random)
|
fmt.Println(result) // [true false] (random)
|
||||||
}
|
}
|
||||||
|
```
|
||||||
|
### <span id="RandNumberOfLength">RandNumberOfLength</span>
|
||||||
|
|
||||||
|
<p>生成指定长度的随机数</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func RandNumberOfLength(len int) int
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>实例:<span style="float:right;display:inline-block;">[运行](todo)</span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/random"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
i := random.RandNumberOfLength(2)
|
||||||
|
fmt.Println(i) // 21 (random number of length 2)
|
||||||
|
}
|
||||||
```
|
```
|
||||||
@@ -52,6 +52,7 @@ import (
|
|||||||
- [ReadFile](#ReadFile)
|
- [ReadFile](#ReadFile)
|
||||||
- [ChunkRead](#ChunkRead)
|
- [ChunkRead](#ChunkRead)
|
||||||
- [ParallelChunkRead](#ParallelChunkRead)
|
- [ParallelChunkRead](#ParallelChunkRead)
|
||||||
|
- [GetExeOrDllVersion](#GetExeOrDllVersion)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
@@ -1074,4 +1075,37 @@ func main() {
|
|||||||
// Jim,21,male
|
// Jim,21,male
|
||||||
// 2
|
// 2
|
||||||
}
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="GetExeOrDllVersion">GetExeOrDllVersion</span>
|
||||||
|
|
||||||
|
<p>Get the version of exe or dll file on windows.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func GetExeOrDllVersion(filePath string) (string, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:<span style="float:right;display:inline-block;">[Run](todo)</span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/fileutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
v, err := fileutil.GetExeOrDllVersion(`C:\Program Files\Tencent\WeChat\WeChat.exe`)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(v)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 3.9.10.19
|
||||||
|
}
|
||||||
```
|
```
|
||||||
@@ -40,6 +40,7 @@ import (
|
|||||||
- [RandStringSlice](#RandStringSlice)
|
- [RandStringSlice](#RandStringSlice)
|
||||||
- [RandBool](#RandBool)
|
- [RandBool](#RandBool)
|
||||||
- [RandBoolSlice](#RandBoolSlice)
|
- [RandBoolSlice](#RandBoolSlice)
|
||||||
|
- [RandNumberOfLength](#RandNumberOfLength)
|
||||||
|
|
||||||
<div STYLE="page-break-after: always;"></div>
|
<div STYLE="page-break-after: always;"></div>
|
||||||
|
|
||||||
@@ -523,4 +524,30 @@ func main() {
|
|||||||
result := random.RandBoolSlice(2)
|
result := random.RandBoolSlice(2)
|
||||||
fmt.Println(result) // [true false] (random)
|
fmt.Println(result) // [true false] (random)
|
||||||
}
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### <span id="RandNumberOfLength">RandNumberOfLength</span>
|
||||||
|
|
||||||
|
<p>Generates a random int number of specified length.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func RandNumberOfLength(len int) int
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Signature:<span style="float:right;display:inline-block;">[Run](todo)</span></b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/random"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
i := random.RandNumberOfLength(2)
|
||||||
|
fmt.Println(i) // 21 (random number of length 2)
|
||||||
|
}
|
||||||
```
|
```
|
||||||
+1
-2
@@ -14,6 +14,7 @@ import (
|
|||||||
"encoding/csv"
|
"encoding/csv"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/validator"
|
||||||
"io"
|
"io"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"net/http"
|
"net/http"
|
||||||
@@ -23,8 +24,6 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/duke-git/lancet/v2/validator"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// FileReader is a reader supporting offset seeking and reading one
|
// FileReader is a reader supporting offset seeking and reading one
|
||||||
|
|||||||
@@ -0,0 +1,83 @@
|
|||||||
|
//go:build windows
|
||||||
|
|
||||||
|
package fileutil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
// tagVS_FIXEDFILEINFO 参考结构体https://learn.microsoft.com/zh-cn/windows/win32/api/verrsrc/ns-verrsrc-vs_fixedfileinfo
|
||||||
|
type tagVS_FIXEDFILEINFO struct {
|
||||||
|
Signature uint32
|
||||||
|
StructVersion uint32
|
||||||
|
FileVersionMS uint32
|
||||||
|
FileVersionLS uint32
|
||||||
|
ProductVersionMS uint32
|
||||||
|
ProductVersionLS uint32
|
||||||
|
FileFlagsMask uint32
|
||||||
|
FileFlags uint32
|
||||||
|
FileOS uint32
|
||||||
|
FileType uint32
|
||||||
|
FileSubtype uint32
|
||||||
|
FileDateMS uint32
|
||||||
|
FileDateLS uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetExeOrDllVersion get the version of exe or dll file on windows.
|
||||||
|
// Play: todo
|
||||||
|
func GetExeOrDllVersion(filePath string) (string, error) {
|
||||||
|
// 加载系统dll
|
||||||
|
versionDLL := syscall.NewLazyDLL("version.dll")
|
||||||
|
getFileVersionInfoSize := versionDLL.NewProc("GetFileVersionInfoSizeW")
|
||||||
|
getFileVersionInfo := versionDLL.NewProc("GetFileVersionInfoW")
|
||||||
|
verQueryValue := versionDLL.NewProc("VerQueryValueW")
|
||||||
|
|
||||||
|
// 转换路径为UTF-16
|
||||||
|
filePathPtr, err := syscall.UTF16PtrFromString(filePath)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("unable to convert file path to UTF-16: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取version信息大小
|
||||||
|
size, _, err := getFileVersionInfoSize.Call(
|
||||||
|
uintptr(unsafe.Pointer(filePathPtr)),
|
||||||
|
0,
|
||||||
|
)
|
||||||
|
if size == 0 {
|
||||||
|
return "", fmt.Errorf("unable to obtain version information size: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载version信息
|
||||||
|
data := make([]byte, size)
|
||||||
|
ret, _, err := getFileVersionInfo.Call(uintptr(unsafe.Pointer(filePathPtr)), 0, size, uintptr(unsafe.Pointer(&data[0])))
|
||||||
|
if ret == 0 {
|
||||||
|
return "", fmt.Errorf("unable to obtain version information: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询version信息
|
||||||
|
var fixedInfo *tagVS_FIXEDFILEINFO
|
||||||
|
var fixedInfoLen uint32
|
||||||
|
u16, err := syscall.UTF16PtrFromString(`\`)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("unable to convert file path to UTF-16: %w", err)
|
||||||
|
}
|
||||||
|
ret, _, err = verQueryValue.Call(
|
||||||
|
uintptr(unsafe.Pointer(&data[0])),
|
||||||
|
uintptr(unsafe.Pointer(u16)),
|
||||||
|
uintptr(unsafe.Pointer(&fixedInfo)),
|
||||||
|
uintptr(unsafe.Pointer(&fixedInfoLen)),
|
||||||
|
)
|
||||||
|
if ret == 0 {
|
||||||
|
return "", fmt.Errorf("unable to query version information: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 转换结构体
|
||||||
|
major := fixedInfo.FileVersionMS >> 16
|
||||||
|
minor := fixedInfo.FileVersionMS & 0xFFFF
|
||||||
|
build := fixedInfo.FileVersionLS >> 16
|
||||||
|
revision := fixedInfo.FileVersionLS & 0xFFFF
|
||||||
|
|
||||||
|
return fmt.Sprintf("%d.%d.%d.%d", major, minor, build, revision), nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
//go:build windows
|
||||||
|
|
||||||
|
package fileutil
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestGetExeOrDllVersion(t *testing.T) {
|
||||||
|
v, err := GetExeOrDllVersion(`C:\Windows\System32\cmd.exe`)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
t.Log(v)
|
||||||
|
}
|
||||||
@@ -1,6 +1,4 @@
|
|||||||
golang.org/x/exp v0.0.0-20221208152030-732eee02a75a h1:4iLhBPcpqFmylhnkbY3W0ONLUYYkDAW9xMFLfxgsvCw=
|
golang.org/x/exp v0.0.0-20221208152030-732eee02a75a h1:4iLhBPcpqFmylhnkbY3W0ONLUYYkDAW9xMFLfxgsvCw=
|
||||||
golang.org/x/exp v0.0.0-20221208152030-732eee02a75a/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
|
golang.org/x/exp v0.0.0-20221208152030-732eee02a75a/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
|
||||||
golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM=
|
|
||||||
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
|
||||||
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
|
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
|
||||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||||
|
|||||||
@@ -221,6 +221,22 @@ func (client *HttpClient) SendRequest(request *HttpRequest) (*http.Response, err
|
|||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AsyncSendRequest send http request with goroutine, pop response and error to channels
|
||||||
|
func (client *HttpClient) AsyncSendRequest(request *HttpRequest, respChan chan *http.Response, errChan chan error) {
|
||||||
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if err := recover(); err != nil {
|
||||||
|
errChan <- fmt.Errorf("%v", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
resp, err := client.SendRequest(request)
|
||||||
|
if err != nil {
|
||||||
|
errChan <- err
|
||||||
|
}
|
||||||
|
respChan <- resp
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
// DecodeResponse decode response into target object.
|
// DecodeResponse decode response into target object.
|
||||||
// Play: https://go.dev/play/p/jUSgynekH7G
|
// Play: https://go.dev/play/p/jUSgynekH7G
|
||||||
func (client *HttpClient) DecodeResponse(resp *http.Response, target any) error {
|
func (client *HttpClient) DecodeResponse(resp *http.Response, target any) error {
|
||||||
|
|||||||
@@ -373,6 +373,45 @@ func TestSendRequestWithFilePath(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestHttpClient_AsyncSendRequest(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
assert := internal.NewAssert(t, "TestHttpClient_Get")
|
||||||
|
|
||||||
|
request := &HttpRequest{
|
||||||
|
RawURL: "https://jsonplaceholder.typicode.com/todos/1",
|
||||||
|
Method: "GET",
|
||||||
|
}
|
||||||
|
|
||||||
|
httpClient := NewHttpClient()
|
||||||
|
respCh := make(chan *http.Response, 20)
|
||||||
|
errCh := make(chan error, 20)
|
||||||
|
for i := 0; i < 50; i++ {
|
||||||
|
httpClient.AsyncSendRequest(request, respCh, errCh)
|
||||||
|
}
|
||||||
|
for i := 0; i < 50; i++ {
|
||||||
|
select {
|
||||||
|
case resp := <-respCh:
|
||||||
|
type Todo struct {
|
||||||
|
UserId int `json:"userId"`
|
||||||
|
Id int `json:"id"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
Completed bool `json:"completed"`
|
||||||
|
}
|
||||||
|
var todo Todo
|
||||||
|
err := httpClient.DecodeResponse(resp, &todo)
|
||||||
|
if err != nil {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
assert.Equal(1, todo.Id)
|
||||||
|
case err := <-errCh:
|
||||||
|
if err != nil {
|
||||||
|
t.Log("net error: ", err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestProxy(t *testing.T) {
|
func TestProxy(t *testing.T) {
|
||||||
config := &HttpClientConfig{
|
config := &HttpClientConfig{
|
||||||
HandshakeTimeout: 20 * time.Second,
|
HandshakeTimeout: 20 * time.Second,
|
||||||
|
|||||||
@@ -327,3 +327,13 @@ func UUIdV4() (string, error) {
|
|||||||
|
|
||||||
return fmt.Sprintf("%x-%x-%x-%x-%x", uuid[0:4], uuid[4:6], uuid[6:8], uuid[8:10], uuid[10:]), nil
|
return fmt.Sprintf("%x-%x-%x-%x-%x", uuid[0:4], uuid[4:6], uuid[6:8], uuid[8:10], uuid[10:]), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RandNumberOfLength 生成一个长度为len的随机数
|
||||||
|
// Play: todo
|
||||||
|
func RandNumberOfLength(len int) int {
|
||||||
|
m := int(math.Pow10(len) - 1)
|
||||||
|
i := int(math.Pow10(len - 1))
|
||||||
|
ret := rand.Intn(m-i+1) + i
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package random
|
|||||||
import (
|
import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/duke-git/lancet/v2/internal"
|
"github.com/duke-git/lancet/v2/internal"
|
||||||
@@ -361,3 +362,9 @@ func TestRandBoolSlice(t *testing.T) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
func TestRandNumberOfLength(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
randi := RandNumberOfLength(6)
|
||||||
|
assert := internal.NewAssert(t, "TestRandNumberOfLength")
|
||||||
|
assert.Equal(6, len(strconv.Itoa(randi)))
|
||||||
|
}
|
||||||
|
|||||||
@@ -195,18 +195,14 @@ func UniqueByConcurrent[T comparable](slice []T, comparator func(item T, other T
|
|||||||
chunks = append(chunks, slice[i:end])
|
chunks = append(chunks, slice[i:end])
|
||||||
}
|
}
|
||||||
|
|
||||||
type resultChunk struct {
|
resultCh := make(chan resultChunk[T], numThreads)
|
||||||
index int
|
|
||||||
data []T
|
|
||||||
}
|
|
||||||
resultCh := make(chan resultChunk, numThreads)
|
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
for i, chunk := range chunks {
|
for i, chunk := range chunks {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func(index int, chunk []T) {
|
go func(index int, chunk []T) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
resultCh <- resultChunk{index, removeDuplicate(chunk, comparator)}
|
resultCh <- resultChunk[T]{index, removeDuplicate(chunk, comparator)}
|
||||||
}(i, chunk)
|
}(i, chunk)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,13 @@ import (
|
|||||||
"golang.org/x/exp/constraints"
|
"golang.org/x/exp/constraints"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// resultChunk is used to store the intermediate results of UniqueByConcurrent.
|
||||||
|
// It is defined separately to be compatible with versions of go up to 1.20.
|
||||||
|
type resultChunk[T comparable] struct {
|
||||||
|
index int
|
||||||
|
data []T
|
||||||
|
}
|
||||||
|
|
||||||
// sliceValue return the reflect value of a slice
|
// sliceValue return the reflect value of a slice
|
||||||
func sliceValue(slice any) reflect.Value {
|
func sliceValue(slice any) reflect.Value {
|
||||||
v := reflect.ValueOf(slice)
|
v := reflect.ValueOf(slice)
|
||||||
|
|||||||
Reference in New Issue
Block a user