You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows批处理:49个文件的可逆全范围随机重排方案问询

解决方案

核心思路

采用线性同余伪随机数生成器(LCG),以输入的9/10位数字密钥为种子,生成可复现的全范围排列,同时严格满足所有约束:

  1. 密钥唯一决定排列逻辑,保证重排与还原的一致性;
  2. 生成排列时自动过滤不动点(原始序号=目标序号);
  3. 检查原始相邻文件的新序号是否不相邻;
  4. 基于全49个元素的随机选择,实现跨范围重排。

重排脚本(shuffle.bat)

@echo off
setlocal enabledelayedexpansion

:: 检查密钥输入合法性
if "%~1"=="" (
    echo 请输入9或10位数字作为密钥
    exit /b 1
)
set "key=%~1"
echo %key% | findstr /r "^[0-9]\{9,10\}$" >nul
if errorlevel 1 (
    echo 密钥必须是9或10位数字
    exit /b 1
)

:: 将密钥转换为LCG种子(取前9位)
set "seed=%key:~0,9%"
set /a seed=seed

:: LCG参数(保证周期覆盖49个元素的所有排列)
set "a=1664525"
set "c=1013904223"
set "m=4294967296"

:: 构建原始序号列表(001-049)
set "orig_list="
for /l %%i in (1,1,49) do (
    set "num=00%%i"
    set "num=!num:~-3!"
    set "orig_list=!orig_list! !num!"
)
set "orig_list=!orig_list:~1!"

:: 生成符合要求的排列
:generate_perm
set "used="
set "perm_list="
set "valid=1"

:: 第一步:生成无不动点的排列
for /l %%i in (1,1,49) do (
    set "orig_num=00%%i"
    set "orig_num=!orig_num:~-3!"
    :find_next
    :: 生成下一个伪随机数
    set /a seed=(a*seed + c) %% m
    set /a rand=seed %% 49 + 1
    set "rand_num=00!rand!"
    set "rand_num=!rand_num:~-3!"
    :: 跳过已使用的序号和原始序号(避免不动点)
    if "!used:!rand_num!=!"=="" if "!rand_num!" neq "!orig_num!" (
        set "used=!used! !rand_num!"
        set "perm_list=!perm_list! !rand_num!"
    ) else (
        goto find_next
    )
)

:: 第二步:检查原始相邻文件的新序号是否不相邻
for /l %%i in (1,1,48) do (
    set "orig_i=00%%i"
    set "orig_i=!orig_i:~-3!"
    set "orig_j=00%%i+1"
    set "orig_j=!orig_j:~-3!"
    :: 获取两个原始序号对应的新序号
    set "new_i="
    set "new_j="
    set "pos=0"
    for %%o in (!orig_list!) do (
        set /a pos+=1
        if "%%o" equ "!orig_i!" (
            set "p_pos=!pos!"
            for %%p in (!perm_list!) do (
                if !p_pos! equ 1 (
                    set "new_i=%%p"
                    goto get_new_i_done
                )
                set /a p_pos-=1
            )
        )
        :get_new_i_done
    )
    set "pos=0"
    for %%o in (!orig_list!) do (
        set /a pos+=1
        if "%%o" equ "!orig_j!" (
            set "p_pos=!pos!"
            for %%p in (!perm_list!) do (
                if !p_pos! equ 1 (
                    set "new_j=%%p"
                    goto get_new_j_done
                )
                set /a p_pos-=1
            )
        )
        :get_new_j_done
    )
    :: 检查新序号是否相邻
    set /a new_i_num=new_i, new_j_num=new_j
    set /a diff=new_i_num - new_j_num
    if !diff! equ 1 if !diff! equ -1 (
        set "valid=0"
        goto reset_perm
    )
)

:: 排列有效,进入重命名步骤
if !valid! equ 1 goto perm_ok

:reset_perm
:: 重置种子,重新生成排列
set "seed=%key:~0,9%"
set /a seed=seed
goto generate_perm

:perm_ok
:: 临时重命名避免冲突
echo 临时重命名文件...
for /l %%i in (1,1,49) do (
    set "orig_num=00%%i"
    set "orig_num=!orig_num:~-3!"
    ren "testfile.exe.!orig_num!" "testfile.exe.tmp.!orig_num!"
)

:: 执行最终重排
echo 执行重排...
set "pos=0"
for %%o in (!orig_list!) do (
    set /a pos+=1
    set "p_pos=!pos!"
    for %%p in (!perm_list!) do (
        if !p_pos! equ 1 (
            ren "testfile.exe.tmp.%%o" "testfile.exe.%%p"
            goto next_file
        )
        set /a p_pos-=1
    )
    :next_file
)

echo 重排完成!
exit /b 0

还原脚本(restore.bat)

@echo off
setlocal enabledelayedexpansion

:: 检查密钥输入合法性
if "%~1"=="" (
    echo 请输入9或10位数字作为密钥
    exit /b 1
)
set "key=%~1"
echo %key% | findstr /r "^[0-9]\{9,10\}$" >nul
if errorlevel 1 (
    echo 密钥必须是9或10位数字
    exit /b 1
)

:: 生成与重排脚本完全一致的排列
set "seed=%key:~0,9%"
set /a seed=seed
set "a=1664525"
set "c=1013904223"
set "m=4294967296"

set "orig_list="
for /l %%i in (1,1,49) do (
    set "num=00%%i"
    set "num=!num:~-3!"
    set "orig_list=!orig_list! !num!"
)
set "orig_list=!orig_list:~1!"

:generate_perm
set "used="
set "perm_list="
set "valid=1"

for /l %%i in (1,1,49) do (
    set "orig_num=00%%i"
    set "orig_num=!orig_num:~-3!"
    :find_next
    set /a seed=(a*seed + c) %% m
    set /a rand=seed %% 49 + 1
    set "rand_num=00!rand!"
    set "rand_num=!rand_num:~-3!"
    if "!used:!rand_num!=!"=="" if "!rand_num!" neq "!orig_num!" (
        set "used=!used! !rand_num!"
        set "perm_list=!perm_list! !rand_num!"
    ) else (
        goto find_next
    )
)

:: 检查排列有效性(和重排脚本一致,确保生成相同序列)
for /l %%i in (1,1,48) do (
    set "orig_i=00%%i"
    set "orig_i=!orig_i:~-3!"
    set "orig_j=00%%i+1"
    set "orig_j=!orig_j:~-3!"
    set "new_i="
    set "new_j="
    set "pos=0"
    for %%o in (!orig_list!) do (
        set /a pos+=1
        if "%%o" equ "!orig_i!" (
            set "p_pos=!pos!"
            for %%p in (!perm_list!) do (
                if !p_pos! equ 1 (
                    set "new_i=%%p"
                    goto get_new_i_done
                )
                set /a p_pos-=1
            )
        )
        :get_new_i_done
    )
    set "pos=0"
    for %%o in (!orig_list!) do (
        set /a pos+=1
        if "%%o" equ "!orig_j!" (
            set "p_pos=!pos!"
            for %%p in (!perm_list!) do (
                if !p_pos! equ 1 (
                    set "new_j=%%p"
                    goto get_new_j_done
                )
                set /a p_pos-=1
            )
        )
        :get_new_j_done
    )
    set /a new_i_num=new_i, new_j_num=new_j
    set /a diff=new_i_num - new_j_num
    if !diff! equ 1 if !diff! equ -1 (
        set "valid=0"
        goto reset_perm
    )
)

if !valid! equ 1 goto perm_ok

:reset_perm
set "seed=%key:~0,9%"
set /a seed=seed
goto generate_perm

:perm_ok
:: 临时重命名避免冲突
echo 临时重命名文件...
for /l %%i in (1,1,49) do (
    set "orig_num=00%%i"
    set "orig_num=!orig_num:~-3!"
    ren "testfile.exe.!orig_num!" "testfile.exe.tmp.!orig_num!"
)

:: 反向映射还原原始命名
echo 执行还原...
set "pos=0"
for %%p in (!perm_list!) do (
    set /a pos+=1
    set "o_pos=!pos!"
    for %%o in (!orig_list!) do (
        if !o_pos! equ 1 (
            ren "testfile.exe.tmp.%%p" "testfile.exe.%%o"
            goto next_restore_file
        )
        set /a o_pos-=1
    )
    :next_restore_file
)

echo 还原完成!
exit /b 0

关键优化说明

  1. 可复现排列:LCG算法以密钥为种子,确保相同密钥生成完全一致的排列,支持精准还原;
  2. 全范围重排:直接从49个元素中随机选择目标序号,彻底打破原有的小范围限制;
  3. 约束满足:
    • 自动过滤不动点,确保所有文件序号都被修改;
    • 额外检查原始相邻文件的新序号是否不相邻;
  4. 冲突避免:先将所有文件临时重命名为.tmp后缀,再执行最终重命名,解决交叉重命名的冲突问题。

使用方法

  • 重排:在命令行执行 shuffle.bat 123456789(替换为你的9/10位密钥)
  • 还原:在命令行执行 restore.bat 123456789(必须使用与重排相同的密钥)

内容的提问来源于stack exchange,提问作者Josh T

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 07:12:43