NiceLeeのBlog 用爱发电 bilibili~

脚本 简单加密文件,以及Github私密repo的附件的上传下载

2024-11-06
nIceLee

阅读:


之所以是脚本,而不是其它,因为省事方便,无需依赖,一(几)行命令可以搞定。

加密文件的思路是:使用一串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脚本,依赖 curljq
./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脚本,依赖 curljq
./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."
}

相似文章

内容
隐藏