之所以是脚本,而不是其它,因为省事方便,无需依赖,一(几)行命令可以搞定。
加密文件的思路是:使用一串Base64的字符串为Key,将它转换为二进制数据,和待加密的数据一起,对齐头部,然后逐个字节进行异或操作。
因为异或操作进行两遍还是原来的值,所以对着已加密的文件再次进行加密,就相当于解密。
如果是文本数据,因为只改头部,所以最好进行压缩打包然后再来处理。
其它二进制文件,根据需要可以适当调整密钥长度。
如果不那么考虑数据安全的话,这应该是最快的、最具性价比的防文件扫描处理方法。
而另一个,之所以针对Github private repo的release的附件的上传和下载,而不是在项目内容里,主要是文件大小限制的考虑。
同时如果针对项目文件的话,commit记录会一直保留,导致项目体积会不断增大,这也是不太好的。
题外话
原以为问AI一下子就可以出来结果,到头来一直跑不通。
修修补补不断对话反馈,过几轮之后之前打的补丁又漏了。
真TM智障啊aaaaaaa!
最后还得是人工检查人工bug修正,好气啊a。
XOR 加密
根据BASE64字符串加密文件头部。
以下为Linux系统脚本,使用的都是基础工具。
./xor.sh file_path_to_deal base64_key_str
#!/bin/bash
## Usage: ./xor.sh file_path_to_deal base64_key_str
DATA_FILE="${1:-raw.data}"
KEY_BASE64="${2:-55yf55qE5pyJ5pKS5aSn6IuP5omT5aSn6IuP5omT5ZWK5ZWK5ZWKYWE=}"
KEY_FILE="$DATA_FILE.key.tmp"
base64 -d <<< "$KEY_BASE64" > $KEY_FILE
base64 -d <<< "55yf55qE5pyJ5pKS5aSn6IuP5omT5aSn6IuP5omT5ZWK5ZWK5ZWKYWE=" > temp
# 检查文件是否存在
if [ ! -f $KEY_FILE ] || [ ! -f $DATA_FILE ]; then
echo "文件 $KEY_FILE 或 $DATA_FILE 不存在!"
exit 1
fi
# 获取文件长度
# key_length=$(wc -c < $KEY_FILE)
# raw_length=$(wc -c < $DATA_FILE)
# key_length=$(du -b $KEY_FILE | awk '{print $1}')
key_length=$(du -b $KEY_FILE | cut -f1)
raw_length=$(du -b $DATA_FILE | cut -f1)
# 如果 $KEY_FILE 的长度大于 $DATA_FILE 的长度,则只读取 $DATA_FILE 的长度
if [ $key_length -gt $raw_length ]; then
key_length=$raw_length
fi
echo "key_length: $key_length, raw_length: $raw_length"
# 打开文件并读取内容
key_file=$(mktemp)
raw_file=$(mktemp)
result_file=$(mktemp)
dd if=$KEY_FILE of=$key_file bs=$key_length count=1
dd if=$DATA_FILE of=$raw_file bs=$key_length count=1
# 初始化结果文件
> $result_file
# 字节异或运算
i=0
while [ $i -lt $key_length ]; do
raw_byte=$(od -An -tu1 -N1 "$raw_file" | head -n1) # Get one byte as unsigned decimal
key_byte=$(od -An -tu1 -N1 "$key_file" | head -n1) # Get one byte as unsigned decimal
xor_byte=$((raw_byte ^ key_byte))
printf "\\$(printf '%03o' "$xor_byte")" >> "$result_file" # Write byte using octal escape
tail -c +2 "$raw_file" > temp_raw && mv temp_raw "$raw_file" #Efficiently remove the first byte from raw_file
tail -c +2 "$key_file" > temp_key && mv temp_key "$key_file" #Efficiently remove the first byte from key_file
# echo "raw_byte: $raw_byte, key_byte: $key_byte, xor_byte: $xor_byte"
i=$((i + 1))
done
# 将结果写回 $DATA_FILE
dd if=$result_file of=$DATA_FILE bs=$key_length count=1 conv=notrunc
# 清理临时文件
rm -f "$key_file" "$raw_file" "$result_file" "$KEY_FILE"
echo "完成!"
以下为Windows系统Powershell脚本,使用的都是基础工具。
.\xor.ps1 -DataFile "path_to_your_file" -KeyBase64 "your_base64_key"
# Set-ExecutionPolicy RemoteSigned
# Set-ExecutionPolicy Unrestricted
# .\xor.ps1 -DataFile "path_to_your_file" -KeyBase64 "your_base64_key"
param (
[string]$DataFile = "raw.data",
[string]$KeyBase64 = "55yf55qE5pyJ5pKS5aSn6IuP5omT5aSn6IuP5omT5ZWK5ZWK5ZWKYWE="
)
# 解码 Base64 密钥
$KeyBytes = [System.Convert]::FromBase64String($KeyBase64)
# 检查文件是否存在
if (-Not (Test-Path $DataFile)) {
Write-Host "文件 $DataFile 不存在!"
exit 1
}
# 获取文件长度
$KeyLength = $KeyBytes.Length
$RawLength = (Get-Item $DataFile).Length
# 如果密钥的长度大于数据文件的长度,则只读取数据文件的长度
if ($KeyLength -gt $RawLength) {
$KeyLength = $RawLength
}
Write-Host "key_length: $KeyLength, raw_length: $RawLength"
# 初始化结果数组
$ResultBytes = New-Object byte[] $KeyLength
# 读取文件内容
$FileStream = [System.IO.File]::OpenRead($DataFile)
try {
# 读取最多 $KeyLength 字节
$RawBytes = New-Object byte[] $KeyLength
$BytesRead = $FileStream.Read($RawBytes, 0, $KeyLength)
# 字节异或运算
for ($i = 0; $i -lt $BytesRead; $i++) {
$ResultBytes[$i] = $RawBytes[$i] -bxor $KeyBytes[$i]
# Write-Host "raw_byte: $($RawBytes[$i]), key_byte: $($KeyBytes[$i]), xor_byte: $($ResultBytes[$i])"
}
}
finally {
# 确保文件流被关闭
$FileStream.Close()
}
# 将结果写回文件的开始部分
$FileStream = [System.IO.File]::Open($DataFile, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Write)
try {
$FileStream.Write($ResultBytes, 0, $ResultBytes.Length)
}
finally {
# 确保文件流被关闭
$FileStream.Close()
}
Write-Host "完成!"
Github repo release附件上传
先查询有没有同名附件,有的话先删除。
以下为Linux脚本,依赖 curl
、jq
。
./gh_up.sh "user/repo" "v1" "gh_token" "assets_name" "file/path/to/upload"
#!/bin/bash
REPO="${1:-user/repo}"
TAG="${2:-v1}"
TOKEN="${3:-gh_token}"
ASSET_NAME="${4:-test.zip}"
FILE_PATH="${5:-$ASSET_NAME}"
# Step 1: Get the Release ID
RELEASE_URL="https://api.github.com/repos/${REPO}/releases/tags/${TAG}"
RELEASE_ID=$(curl -s -H "Accept: application/vnd.github+json" -H "Authorization: token ${TOKEN}" "${RELEASE_URL}" | jq -r '.id')
if [[ -z "$RELEASE_ID" ]]; then
echo "Error: Release ${TAG} not found."
exit 1
fi
# Step 2: List existing assets
ASSETS_URL="https://api.github.com/repos/${REPO}/releases/${RELEASE_ID}/assets"
ASSETS=$(curl -s -H "Authorization: token ${TOKEN}" "${ASSETS_URL}")
# Step 3: Check if the asset exists and delete it
ASSET_ID=$(echo "$ASSETS" | jq --arg ASSET_NAME "$ASSET_NAME" -r '.[] | select(.name == $ASSET_NAME) | .id')
if [[ -n "$ASSET_ID" ]]; then
DELETE_URL="https://api.github.com/repos/${REPO}/releases/assets/${ASSET_ID}"
curl -s -X DELETE -H "Authorization: token ${TOKEN}" "${DELETE_URL}"
if [[ $? -ne 0 ]]; then
echo "Error: Failed to delete existing asset ${ASSET_NAME}."
exit 1
fi
echo "Existing asset ${ASSET_NAME} deleted."
fi
# Step 4: Upload the new asset
UPLOAD_URL="https://uploads.github.com/repos/${REPO}/releases/${RELEASE_ID}/assets?name=${ASSET_NAME}"
#curl -X POST -H "Authorization: token ${TOKEN}" -H "Content-Type: application/octet-stream" -F "file=@${FILE_PATH}" "${UPLOAD_URL}"
curl -X POST -H "Authorization: token ${TOKEN}" -H "Content-Type: application/octet-stream" --data-binary "@${FILE_PATH}" "${UPLOAD_URL}"
if [[ $? -eq 0 ]]; then
echo "Asset ${ASSET_NAME} uploaded successfully."
else
echo "Error uploading asset ${ASSET_NAME}."
fi
以下为Windows系统Powershell脚本,使用的都是基础工具。
# Set-ExecutionPolicy RemoteSigned
# Set-ExecutionPolicy Unrestricted
# .\github_upload.ps1 -Repo "user/repo" -Tag "v1" -Token "gh_token" -AssetName "test.zip" -FilePath "test.zip"
param(
[string]$Repo = "user/repo",
[string]$Tag = "v1",
[string]$Token = "gh_token",
[string]$AssetName = "test.zip",
[string]$FilePath = "test.zip"
)
# Step 1: Get the Release ID
$ReleaseUrl = "https://api.github.com/repos/$Repo/releases/tags/$Tag"
$ReleaseResponse = Invoke-RestMethod -Uri $ReleaseUrl -Headers @{ "Authorization" = "token $Token"; "Accept" = "application/vnd.github+json" } -Method Get
if (-not $ReleaseResponse.id) {
Write-Host "Error: Release $Tag not found."
exit 1
}
$ReleaseId = $ReleaseResponse.id
# Step 2: List existing assets
$AssetsUrl = "https://api.github.com/repos/$Repo/releases/$ReleaseId/assets"
$Assets = Invoke-RestMethod -Uri $AssetsUrl -Headers @{ "Authorization" = "token $Token" } -Method Get
# Step 3: Check if the asset exists and delete it
$AssetExists = $false
foreach ($Asset in $Assets) {
if ($Asset.name -eq $AssetName) {
$AssetId = $Asset.id
$DeleteUrl = "https://api.github.com/repos/$Repo/releases/assets/$AssetId"
Invoke-RestMethod -Uri $DeleteUrl -Headers @{ "Authorization" = "token $Token" } -Method Delete
if ($?) {
Write-Host "Existing asset $AssetName deleted."
} else {
Write-Host "Error: Failed to delete existing asset $AssetName."
exit 1
}
$AssetExists = $true
break
}
}
# Step 4: Upload the new asset
$UploadUrl = "https://uploads.github.com/repos/$Repo/releases/$ReleaseId/assets?name=$AssetName"
$FileStream = [System.IO.File]::OpenRead($FilePath)
$ContentType = "application/octet-stream"
try {
$Response = Invoke-RestMethod -Uri $UploadUrl -Headers @{ "Authorization" = "token $Token"; "Content-Type" = $ContentType } -Method Post -Body $FileStream
Write-Host "Asset $AssetName uploaded successfully."
} catch {
Write-Host "Error uploading asset $AssetName."
} finally {
$FileStream.Close()
}
Github repo release附件下载
以下为Linux脚本,依赖 curl
、jq
。
./gh_down.sh "user/repo" "v1" "gh_token" "assets_name" "path/to/save"
#!/bin/bash
# ./gh_down.sh user/repo v1 gh_token test.zip ./test.zip
REPO="${1:-user/repo}"
TAG="${2:-v1}"
TOKEN="${3:-gh_token}"
ASSET_NAME="${4:-test.zip}"
DOWNLOAD_PATH="${5:-$ASSET_NAME}"
# Step 1: Get the Release ID
RELEASE_URL="https://api.github.com/repos/${REPO}/releases/tags/${TAG}"
RELEASE_ID=$(curl -s -H "Accept: application/vnd.github+json" -H "Authorization: Bearer ${TOKEN}" "${RELEASE_URL}" | jq -r '.id')
if [[ -z "$RELEASE_ID" ]]; then
echo "Error: Release ${TAG} not found."
exit 1
fi
# Step 2: List existing assets
ASSETS_URL="https://api.github.com/repos/${REPO}/releases/${RELEASE_ID}/assets"
ASSETS=$(curl -s -H "Authorization: Bearer ${TOKEN}" "${ASSETS_URL}")
# Correctly parse the JSON array
ASSETS_ARRAY=$(echo "${ASSETS}" | jq -r '.[]')
# Step 3: Find the Asset URL
# echo "${ASSETS}"
ASSET_ID=$(echo "$ASSETS" | jq --arg ASSET_NAME "$ASSET_NAME" -r '.[] | select(.name == $ASSET_NAME) | .id')
ASSET_URL="https://api.github.com/repos/${REPO}/releases/assets/${ASSET_ID}"
if [[ -z "$ASSET_ID" ]]; then
echo "Error: Asset ${ASSET_NAME} not found."
exit 1
fi
echo "Asset URL: ${ASSET_URL}"
# Step 4: Download the Asset
curl -L -o "${DOWNLOAD_PATH}" -H "Authorization: Bearer ${TOKEN}" -H "Accept: application/octet-stream" "${ASSET_URL}"
if [[ $? -eq 0 ]]; then
echo "Asset ${ASSET_NAME} downloaded successfully to ${DOWNLOAD_PATH}."
else
echo "Error downloading asset ${ASSET_NAME}."
fi
以下为Windows系统Powershell脚本,使用的都是基础工具。
# Set-ExecutionPolicy RemoteSigned
# Set-ExecutionPolicy Unrestricted
# .\gh_down.ps1 -Repo "your/repo" -Tag "v1" -Token "your_github_token" -AssetName "test.zip" -DownloadPath "path_to_download/test.zip"
param(
[string]$Repo = "user/repo",
[string]$Tag = "v1",
[string]$Token = "gh_token",
[string]$AssetName = "test.zip",
[string]$DownloadPath = "test.zip"
)
# 强制使用 TLS 1.2
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
# Step 1: Get the Release ID
$ReleaseUrl = "https://api.github.com/repos/$Repo/releases/tags/$Tag"
$ReleaseResponse = Invoke-RestMethod -Uri $ReleaseUrl -Headers @{ "Authorization" = "token $Token"; "Accept" = "application/vnd.github+json" } -Method Get
if (-not $ReleaseResponse.id) {
Write-Host "Error: Release $Tag not found."
exit 1
}
$ReleaseId = $ReleaseResponse.id
# Step 2: List existing assets
$AssetsUrl = "https://api.github.com/repos/$Repo/releases/$ReleaseId/assets"
$Assets = Invoke-RestMethod -Uri $AssetsUrl -Headers @{ "Authorization" = "token $Token" } -Method Get
# Step 3: Find the Asset URL
$AssetUrl = $null
foreach ($Asset in $Assets) {
if ($Asset.name -eq $AssetName) {
# $AssetUrl = $Asset.browser_download_url
$AssetId = $Asset.id
$AssetUrl = "https://api.github.com/repos/$Repo/releases/assets/$AssetId"
break
}
}
if (-not $AssetUrl) {
Write-Host "Error: Asset $AssetName not found."
exit 1
}
Write-Host "Asset URL: $AssetUrl"
# Step 4: Download the Asset
# Invoke-WebRequest -Uri $AssetUrl -Headers @{ "Authorization" = "Bearer $Token" } -OutFile $DownloadPath
Invoke-RestMethod -Uri $AssetUrl -Headers @{ "Authorization" = "Bearer $Token"; "Accept" = "application/octet-stream" } -OutFile $DownloadPath
if ($?) {
Write-Host "Asset $AssetName downloaded successfully to $DownloadPath."
} else {
Write-Host "Error downloading asset $AssetName."
}