用来生成可用在代码中的,指定长度hex字符脚本。默认为16个字条表示。

import argparse
import secrets

def generate_random_hex_string(length):
    # 生成指定长度的随机字节
    random_bytes = secrets.token_bytes(length)
    
    # 将每个字节转化为以0x开头的十六进制字符串
    hex_string = ','.join(f'0x{byte:02x}' for byte in random_bytes)
    
    return hex_string

def main():
    # 命令行参数解析
    parser = argparse.ArgumentParser(description="生成随机十六进制字节串")
    parser.add_argument('length', type=int, nargs='?', default=16, 
                        help="生成十六进制随机数的长度,默认为16")
    
    args = parser.parse_args()
    
    # 生成随机十六进制字符串
    result = generate_random_hex_string(args.length)
    
    # 输出结果
    print(result)

# 检查是否直接运行该脚本
if __name__ == '__main__':
    main()

以下的C++方法可以判断一个文本是否符合base64的编码规则。

bool IsBase64String(std::string_view str)
{
    auto length = str.length();

    if (!length || length % 4)
    {
        return false;
    }

    if (str[length - 1] == '=')
    {
        --length;
        if (str[length - 1] == '=')
        {
            --length;
        }
    }

    auto base64Part = str.substr(0, length);
    for (auto& c : base64Part)
    {
        if (!(std::isalnum(c) || c == '+' || c == '/'))
        {
            return false;
        }
    }

    return true;
}

需要从文本读入一组二进制数据。希望尽可能多的兼容各种文本形式。比如0x1234567890abcdef或1234567890abcdef或12 34 45 78 90 ab cd ef或12,34,56,78,90,ab,cd,ef或者0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef这样的文本都可以正确的解析成二进制数据,还要需要有无效格式的判断。
以下是C++实现:

std::vector<uint8_t> ParseHexToBytes(std::string_view input)
{
    std::vector<uint8_t> bytes;
    bytes.reserve(1024);

    std::string currentByte;
    currentByte.reserve(2);

    for (size_t i = 0; i < input.size(); ++i)
    {
        char c = std::tolower(input[i]);

        if (c == '0' && i + 1 < input.size() && (input[i + 1] == 'x' || input[i + 1] == 'X'))
        {
            ++i;
            continue;
        }

        if (std::ispunct(c) || std::isblank(c))
        {
            continue;
        }

        if (!std::isxdigit(c))
        {
            return {};
        }

        currentByte += c;

        if (currentByte.size() == 2)
        {
            uint8_t byte = static_cast<uint8_t>(std::stoi(currentByte, nullptr, 16));
            bytes.push_back(byte);
            currentByte.clear();
        }
    }

    return bytes;
}

之前整理过一篇《直接检出chromium某tag的完整可构建源码。》的文章。

这个方法中,在git fetch这个步骤需要花费大量的时间。
经过对git命令的研究之后,终于再总结出一个最快速的从零开始,直接check出指定的tag代码的方法。旧的方法完全可以淘汰了。

首先,还是先创建代码存放目前。不同的是,这里不需要创建src目录。

mkdir chromium
cd chromium

然后还是创建.gclient文件:

solutions = [
  {
    "name": "src",
    "url": "https://chromium.googlesource.com/chromium/src.git",
    "managed": False,
    "custom_deps": {},
    "custom_vars": {"checkout_pgo_profiles": True,},
  },
]

如果是要构建android平台的浏览器,就在这个文件最后添加一行内容:

target_os = ["android"]

到这里,还跟之前的方法相差不多。但是接下来就不一样了。以当前最新的官方正式版本112.0.5615.50为例。
直接克隆这个tag的代码:

git clone --depth 2 -b 112.0.5615.50 https://chromium.googlesource.com/chromium/src.git

这里要注意,其中--depth必须为2,原因后面会说到。
这个步骤,代替了原来的git fetch。并且深度只有2,所以原本需要同步的30+G的数据,变成只有区区1+G。这样就节省下了大量的时间和流量。

接下来,还是同步第三方工程和工具链。

gclient sync -D --with_branch_heads --with_tags

这里就要提一下为什么上面--depth必须为2。因为gclient在runhook的时候,是会根据git的提交日志来创建当前的版本信息。而深度为1的时候,就失去了需要的日志内容。会导致下面两个文件内的信息为空。当然,这样也会不导致编译失败,但是在浏览器内就无法看到构建的版本信息了。

src/build/util/LASTCHANGE
src/gpu/config/gpu_lists_version.h

这时,这份源码就已经可以编译出一份完整的chromium浏览器了。
同时,在这份源码的基础上,同样可以继续更新后续的代码。比如需要更新到112.0.5615.67这个tag。

cd src
git fetch origin tag 112.0.5615.67
git checkout -b local_112.0.5615.67 112.0.5615.67
cd ..
gclient sync -D --with_branch_heads --with_tags

而这个更新过程,同步的数据也非常小,非常快捷。因此这个方法应该是最终的chromium代码同步方法了。

ubuntu在内核的更新上,还是非常勤快的。如果每个更新都即时跟进的话,很快就是积累下很多旧内核。
旧内核不仅占用空间,而且看着难受……

使用sudo apt autoremove可以移除旧内核文件,但是在dpkg --get-selections中还会出现,并被标记为deinstall状态。同样看着难受……

并且如果是系统大版本更新,那旧内核也不能通过上面那个命令来移除。这时候就需要用别的方法来干净的删除内核。

首先列出已安装的内核包:

dpkg --get-selections | grep linux-

通过sudo apt-get purge来指定要删除的内核包。比如我要删除5.13的所有内核包:

sudo apt-get purge linux-image-5.13.* linux-modules-5.13.* linux-headers-5.13.* linux-oracle-5.13*

如果已经通过sudo apt autoremove移除,并留下deinstall状态的内核。那可以用下面的命令删除所有deinstall状态的包。

sudo dpkg --purge `dpkg --get-selections | grep deinstall | cut -f1`