前置条件
- macOS Sequoia (15.2)
- MacBook Pro 2023-Apple M2 Pro (4能效核、8性能核、32GB内存、2TB磁盘)
- FreeCAD_weekly-builds-39896-conda-macOS-arm64-py311
问题现象
从 FreeCAD 下载每周构建版本,则在安装后会报错“已损坏,无法打开。 您应该将它移到废纸篓”,类似下图:
从 FreeCAD 下载每周构建版本,则在安装后会报错“已损坏,无法打开。 您应该将它移到废纸篓”,类似下图:
在OpenWRT设备上,可以通过以下两种命令来更新系统所有软件包:
仅更新LuCI相关的软件包(Web管理界面):
|
1 |
$ opkg list-upgradable | grep luci- | cut -f 1 -d ' ' | xargs opkg upgrade --force-overwrite |
更新所有可升级的软件包(包括系统内核和其他组件):
|
1 |
$ opkg list-upgradable | cut -f 1 -d ' ' | xargs opkg upgrade --force-overwrite |
保持OpenWRT系统及其软件包的最新版本,不仅能让系统享有最新的功能和性能优化,还能显著提高设备的安全性。每一次更新,通常都包含以下内容:
安全补丁:随着时间的推移,可能会发现系统中的安全漏洞。更新能够及时修复这些漏洞,避免设备受到攻击。
功能改进:新的软件包版本往往带来新功能,或改进现有功能,让系统更加易用和强大。
性能优化:定期更新不仅能修复Bug,还能提升系统的性能,使网络设备运行更加流畅。
兼容性和稳定性:更新可能包含对硬件和软件兼容性的提升,减少运行中出现的问题,保持系统的长期稳定性。
本文将从最基本的更新软件包源开始,接着详细介绍两种可供选择的升级方式——只更新LuCI相关组件或更新所有软件包。用户可以根据需求选择相应的命令。
无论你打算只更新LuCI相关的组件,还是更新整个系统,首先都需要刷新软件包源列表。这一步可以确保系统从最新的软件包存储库中获取信息,并知道哪些软件包有更新可用。
|
1 |
$ opkg update |
详细解释:
opkg update:这个命令不会直接升级软件包,而是更新系统的软件包源列表。它会连接到OpenWRT的软件包存储库,获取最新的包信息,包括版本号、依赖关系等。执行完这个命令后,设备将知道哪些软件包可以升级,从而为后续的升级操作做好准备。
如果你只想更新LuCI Web管理界面和相关插件,而不想影响其他系统组件,可以使用以下命令:
|
1 |
$ opkg list-upgradable | grep luci- | cut -f 1 -d ' ' | xargs opkg upgrade --force-overwrite |
详细解释:
opkg list-upgradable:列出当前系统中所有可以升级的软件包及其版本信息。输出内容通常会包括包名、当前安装版本和最新可用版本。
例如:
|
1 2 3 |
luci-app-firewall - 1.1-1 - 1.2-1 luci-base - 1.1-1 - 1.2-1 |
这表示 luci-app-firewall 和 luci-base 都有新版本可以升级。
grep luci-:筛选出所有以 “luci-” 开头的软件包。LuCI相关的所有软件包名称通常都以“luci-”开头,如 luci-base、luci-app-firewall 等。因此,这个命令确保只筛选和更新LuCI相关的软件包。
cut -f 1 -d ' ':将筛选结果中的包名提取出来,忽略版本信息。输出的内容会类似于:
|
1 2 3 |
luci-app-firewall luci-base |
xargs opkg upgrade:xargs 是用于将前面筛选出的包名传递给 opkg upgrade 命令的工具。它将每个包名作为参数传递给 opkg upgrade,然后逐个升级这些包。
使用场景:
如果你只关心Web界面和相关管理功能的升级,而其他系统组件都不需要更改,可以选择这种方法。这可以减少升级的范围,降低更新过程中出现问题的风险。
如果你希望更新系统中所有的软件包,包括内核、应用程序、以及网络相关工具,可以使用以下命令:
|
1 |
$ opkg list-upgradable | cut -f 1 -d ' ' | xargs opkg upgrade --force-overwrite |
详细解释:
opkg list-upgradable:与前面一样,用于列出所有可以升级的软件包。它会显示每个软件包的名称及其版本更新信息。
cut -f 1 -d ' ':这条命令将所有软件包名称提取出来,去掉版本信息。和前面的命令类似,它将结果简化为只有包名。
xargs opkg upgrade:这一步是将所有提取出的包名传递给 opkg upgrade 命令,然后逐一升级这些包。这是一次性更新系统中所有软件包的命令,确保系统中的每一个组件都保持最新。
使用场景:
当你希望确保系统中的所有软件包都保持最新,或者希望全面更新系统时,这条命令非常适合。它不仅会更新LuCI,还会更新内核和所有安装的应用程序、驱动程序等。
在执行更新前,请注意以下几点:
内核更新的风险:更新所有软件包时,可能会涉及内核更新。内核更新可能会提升性能或修复安全问题,但同时也可能导致设备重启,或某些依赖于旧内核的功能失效。如果你使用了第三方驱动或定制的内核模块,更新内核可能会导致系统不稳定。
存储空间不足:OpenWRT设备的存储和内存往往有限,更新大量软件包时,可能会耗尽可用的存储空间。请务必提前检查设备的存储空间,以避免更新过程中出现失败,或导致系统崩溃。可以使用以下命令检查剩余存储空间:
|
1 |
$ df -h |
备份系统配置:在执行大规模更新之前,务必备份你的系统配置文件。这可以通过LuCI Web界面或者命令行来完成。如果更新过程中出现问题,备份将是恢复系统的关键。
逐步更新的建议:如果设备正在正常运行,建议分阶段进行更新。例如,可以先更新LuCI Web界面,观察系统的稳定性,再逐步更新其他软件包,避免一次性大规模更新可能导致的系统问题。
为了确保在更新过程中万一出现问题时能够快速恢复系统,建议在更新前进行配置备份。可以使用以下两种方式备份:
通过LuCI界面:登录LuCI Web管理界面,导航到“系统 > 备份/升级”页面,点击“生成备份”按钮,下载配置文件到本地。
通过命令行备份:
|
1 |
$ sysupgrade -b /tmp/backup.tar.gz |
然后可以通过SCP或FTP下载该备份文件到本地电脑。
通过上述命令,OpenWRT用户可以轻松更新系统中的所有软件包。你可以选择仅更新LuCI Web界面,或者全面升级所有系统组件(包括内核)。在执行更新前,务必确保做好配置备份并确认设备有足够的存储空间,这将帮助你保持系统的安全性、功能完备性以及长期稳定性。
最近在和公司其他项目组沟通联调H5的时候,意外发现对方发过来的地址可以加载,但是没有办法正常刷新。
尤其是对方服务器上已经重新部署页面,二次进入的情况下,依旧显示上一次加载过的内容,直到应用重启为止。
写个 WebView 的 demo,然后在 WebViewClient 的所有方法加上日志来监控网页的运行情况。
此处假定测试网址为 https://www.mobibrw.com/#/?p=43064
对网页第一次加载可以正常加载(即调用了 onPageStarted 和 onPageFinished )。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
I/MyWebView: shouldInterceptRequest: https://www.mobibrw.com/#/?p=43064 I/MyWebView: onProgressChanged: 10 I/MyWebView: shouldOverrideUrlLoading: url:https://www.mobibrw.com/#/?p=43064 I/MyWebView: onPageStarted: url:https://www.mobibrw.com/#/?p=43064, favicon :null ............省略中间无关日志......... I/MyWebView: onPageFinished: url:https://www.mobibrw.com/#/?p=43064 I/MyWebView: onProgressChanged: 70 I/MyWebView: onProgressChanged: 100 |
第二次调用 loadUrl() 加载的时候只会刷新图标,不会真的重新加载网页(只调用了 onPageFinished )。
|
1 2 3 4 5 6 7 |
I/MyWebView: onProgressChanged: 10 I/MyWebView: doUpdateVisitedHistory: url:https://www.mobibrw.com/#/?p=43064, isReload:false I/MyWebView: onPageFinished: url:https://www.mobibrw.com/#/?p=43064 I/MyWebView: onProgressChanged: 100 |
最后发现当我们第二次加载链接的时候,如果调用的是 webview.loadUrl(url) ,就无法刷新。
但是如果调用的是 webview.reload(url) ,就可以正常刷新网页。
调用 reload 时日志如下:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
I/MyWebView: onProgressChanged: 10 I/MyWebView: shouldInterceptRequest: url:https://www.mobibrw.com/#/?p=43064 I/MyWebView: shouldOverrideUrlLoading: url:https://www.mobibrw.com/#/?p=43064 I/MyWebView: onPageStarted: url:https://www.mobibrw.com/#/?p=43064, favicon :android.graphics.Bitmap@a1689fc I/MyWebView: onProgressChanged: 23 ............省略中间无关日志......... I/MyWebView: onProgressChanged: 100 I/MyWebView: onPageFinished: url:https://www.mobibrw.com/#/?p=43064 |
知道了调用 reload 可以重刷网页,调用 loadUrl 无法重刷网页,问题就在于这两个方法的差别了。
经过查找,得知了真正原因是因为对方的 URL 带了 #,所以导致 loadUrl 不会刷新网页。
将网址改为 https://www.mobibrw.com/?p=43064,再次调用 loadUrl,第二次加载日志如下:
|
1 2 3 4 5 6 7 8 9 10 11 |
I/MyWebView: shouldInterceptRequest: url:https://www.mobibrw.com/?p=43064 I/MyWebView: onProgressChanged: 10 I/MyWebView: onPageStarted: url:https://www.mobibrw.com/?p=43064, favicon :android.graphics.Bitmap@1d36963 I/MyWebView: onProgressChanged: 70 I/MyWebView: onProgressChanged: 100 I/MyWebView: onPageFinished: url:https://www.mobibrw.com/?p=43064 |
可以看到有正常执行 onPageStarted 和 onPageFinished 。
那么为什么 URL 里面带了个 #,我们的 WebView 就无法通过 loadUrl 刷新网页了呢?
简单来说,URL 中 # 以及其后面的部分,是客户端这边的位置定位符,在加载网页的时候并不会真正的发送给服务端。
我们的测试网址由于带有 #,所以无论怎么调用 loadUrl,他都判断我们只是改变了网页内部的相对位置(虽然实际上我们并没有改变),不会重新加载这个网页,只是加载网页图标。
那为什么 webview.reload 又可以重刷网页呢,实际上是因为 loadUrl 默认会有缓存策略,而 reload 是无视缓存策略强制刷新的,所以我们拿这个地址去浏览器运行,是可以正常刷新的。
loadUrl 会有缓存策略,二次加载遇到带 # 的网页不会刷新,reload 无视缓存策略会强制刷新。
输入法切换到 “简体拼音”, 然后按下自带键盘上的 左侧 Shift 与 - 按键,目的是按出下划线,会导致 OpenSCAD 闪退,崩溃堆栈如下:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
------------------------------------- Translated Report (Full Report Below) ------------------------------------- Process: OpenSCAD [87606] Path: /Applications/OpenSCAD.app/Contents/MacOS/OpenSCAD Identifier: org.openscad.OpenSCAD Version: 2024.12 (2024.12.30) Code Type: ARM-64 (Native) Parent Process: launchd [1] User ID: 501 Date/Time: 2025-01-07 10:43:50.0163 +0800 OS Version: macOS 15.2 (24C101) Report Version: 12 Anonymous UUID: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX Sleep/Wake UUID: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX Time Awake Since Boot: 1700000 seconds Time Since Wake: 5033 seconds System Integrity Protection: enabled Crashed Thread: 0 Dispatch queue: com.apple.main-thread Exception Type: EXC_CRASH (SIGABRT) Exception Codes: 0x0000000000000000, 0x0000000000000000 Termination Reason: Namespace SIGNAL, Code 6 Abort trap: 6 Terminating Process: OpenSCAD [87606] Application Specific Information: abort() called Thread 0 Crashed:: Dispatch queue: com.apple.main-thread 0 libsystem_kernel.dylib 0x18fec7720 __pthread_kill + 8 1 libsystem_pthread.dylib 0x18fefff70 pthread_kill + 288 2 libsystem_c.dylib 0x18fe0c908 abort + 128 3 libc++abi.dylib 0x18feb644c abort_message + 132 4 libc++abi.dylib 0x18fea4a24 demangling_terminate_handler() + 320 5 libobjc.A.dylib 0x18fb4d3f4 _objc_terminate() + 172 6 libc++abi.dylib 0x18feb5710 std::__terminate(void (*)()) + 16 7 libc++abi.dylib 0x18feb8cdc __cxxabiv1::failed_throw(__cxxabiv1::__cxa_exception*) + 88 8 libc++abi.dylib 0x18feb8c84 __cxa_throw + 92 9 libqscintilla2_qt6.15.dylib 0x1025f20f8 0x10245c000 + 1663224 10 libqscintilla2_qt6.15.dylib 0x1025bb4e8 0x10245c000 + 1438952 11 libqscintilla2_qt6.15.dylib 0x1025ed018 0x10245c000 + 1642520 12 libqscintilla2_qt6.15.dylib 0x10246f358 QsciScintillaBase::keyPressEvent(QKeyEvent*) + 448 13 QtWidgets 0x1039d17d8 QWidget::event(QEvent*) + 556 14 QtWidgets 0x103a4f780 QFrame::event(QEvent*) + 56 15 QtWidgets 0x103988c58 QApplicationPrivate::notify_helper(QObject*, QEvent*) + 272 16 QtWidgets 0x103989cec QApplication::notify(QObject*, QEvent*) + 972 17 OpenSCAD 0x100a85440 OpenSCADApp::notify(QObject*, QEvent*) + 28 18 QtCore 0x104dd124c QCoreApplication::notifyInternal2(QObject*, QEvent*) + 292 19 QtWidgets 0x1039e43a0 QWidgetWindow::event(QEvent*) + 168 20 QtWidgets 0x103988c58 QApplicationPrivate::notify_helper(QObject*, QEvent*) + 272 21 QtWidgets 0x103989af8 QApplication::notify(QObject*, QEvent*) + 472 22 OpenSCAD 0x100a85440 OpenSCADApp::notify(QObject*, QEvent*) + 28 23 QtCore 0x104dd124c QCoreApplication::notifyInternal2(QObject*, QEvent*) + 292 24 QtGui 0x102e1b110 QGuiApplicationPrivate::processKeyEvent(QWindowSystemInterfacePrivate::KeyEvent*) + 260 25 QtGui 0x102e70c24 QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) + 396 26 QtGui 0x102e70810 QWindowSystemInterface::flushWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) + 284 27 libqcocoa.dylib 0x1038446d4 -[QNSView(Keys) handleKeyEvent:] + 1760 28 libqcocoa.dylib 0x10384540c -[QNSView(Keys) keyDown:] + 76 29 AppKit 0x193c77e5c -[NSWindow(NSEventRouting) _reallySendEvent:isDelayedEvent:] + 316 30 AppKit 0x193c77b50 -[NSWindow(NSEventRouting) sendEvent:] + 284 31 libqcocoa.dylib 0x10384d16c -[QNSWindow sendEvent:] + 824 32 AppKit 0x1944b4378 -[NSApplication(NSEventRouting) sendEvent:] + 2360 33 libqcocoa.dylib 0x1037f2330 -[QNSApplication sendEvent:] + 68 34 AppKit 0x1940bb4e8 -[NSApplication _handleEvent:] + 60 35 AppKit 0x193b44088 -[NSApplication run] + 520 36 libqcocoa.dylib 0x1037fde9c QCocoaEventDispatcher::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) + 1904 37 QtCore 0x104ddabc4 QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) + 532 38 QtCore 0x104dd18d8 QCoreApplication::exec() + 112 39 OpenSCAD 0x100a34c9c gui(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>>>&, std::__1::__fs::filesystem::path const&, int, char**) + 2076 40 OpenSCAD 0x100716b10 main + 18796 41 dyld 0x18fb80274 start + 2840 |
|
代号 Code |
型号 Model |
安装方式 Mounting type |
外形尺寸 Dimensions (mm |
参数 Sections |
最大可变容量 Max.var.Capacitance(pF) |
最小容量 Min.Capacitance(pF) |
容量公差 Tolerance of Capacitance(pF) |
|
009 |
CBM-223P |
1 |
20.5×20.5×12.5 |
AM-2 |
(o):59.2 |
(O):5±2 |
(O):±(2pF+2%) |
| 型 号 Model |
联别Section | 转角关系及电容增量 Coeff of Rotation and Cap Swing (%pF) | ||||||||||||||
| 100 | 90 | 80 | 75 | 70 | 60 | 50 | 40 | 30 | 25 | 20 | 10 | (3) | ||||
|
CBM-223P |
AM | OSC | 59.2 | 55.2 | 50.9 | 48.5 | 46.2 | 41.0 | 35.0 | 28.4 | 21.0 | 16.9 | 12.9 | 4.8 | 0 | |
| ANT | 141.6 | 126.3 | 111.2 | 103.7 | 96.1 | 80.4 | 64.3 | 48.5 | 33.2 | 25.7 | 18.5 | 6.2 | 0 | |||
As we announced earlier with the 3.0 stable release, due to decreased usage, that release was the last one to support 32-bit iOS devices and iOS versions 9 and 10. This change affects the iPhone 4S, iPhone 5, iPhone 5C, and the 2nd, 3d, and 4th generation iPad devices. The 3.3 stable version of Flutter and all following stable releases no longer support 32-bit iOS devices and iOS versions 9 and 10. This means that apps built against Flutter 3.3 and later won’t run on those devices.
In the Q4 2022 stable release, we expect to drop support for macOS versions 10.11 and 10.12. This means that apps built against stable Flutter SDKs after that point will no longer work on these versions, and the minimum macOS version supported by Flutter will increase to 10.13 High Sierra.
Bitcode will no longer be accepted for iOS app submission in the upcoming Xcode 14 release, and projects with bitcode enabled will emit a build warning in this version of Xcode. In light of this, Flutter will drop support for bitcode in a future stable release.
By default, Flutter apps don’t have bitcode enabled, and we don’t expect this to impact many developers. However, if you have enabled bitcode manually in your Xcode project, disable it as soon as you upgrade to Xcode 14. You can do so by opening ios/Runner.xcworkspace and setting the build setting Enable Bitcode to No. Add-to-app developers should disable it in the host Xcode project.
See Apple’s documentation to learn more about bitcode distribution.
As of the current release, Flutter supports the following platforms as part of Google-tested and best-effort platform tier:
| Platform | Version | Channels |
|---|---|---|
| Android | API 16 (Android 4.1) & above | All |
| iOS | iOS 11 & above | All |
| Linux | Debian, 64-bit | All |
| macOS | El Capitan (10.11) & above | All |
| Web | Chrome 84 & above | All |
| Web | Firefox 72.0 & above | All |
| Web | Safari on El Capitan & above | All |
| Web | Edge 1.2.0 & above | All |
| Windows | Windows 7 & above, 64-bit | All |
All channels include master, beta, and stable channels.
| Platform | Version |
|---|---|
| Android | Android SDK 19–30* |
| iOS | 14-15 |
| Linux | Debian 10 |
| Linux | Ubuntu 18.04 LTS |
| macOS | Monterey (12) & above |
| Web | Chrome 84 |
| Web | Firefox 72.0 |
| Web | Safari / Catalina |
| Web | Edge 1.2.0 |
| Windows | Windows 10 |
* Passing tests on Android SDK 19 also confers a passing result on SDK 20. This is because Android SDK 20 has additional support for Android Wear, but otherwise no new or deprecated API.
| Platform | Version |
|---|---|
| Android | Android SDK 16–18 |
| iOS | iOS 11-13 |
| Linux | Debian 11 |
| Linux | Debian 9 & below |
| Linux | Ubuntu 20.04 |
| Linux | Ubuntu 22.04 (Aspirational Google-tested platform) |
| macOS | El Capitan (10.11) - Big Sur (11)* |
| Windows | Windows 11 (Aspirational Google-tested platform) |
| Windows | Windows 8 |
| Windows | Windows 7 |
* Flutter 3.3 is the last stable release with macOS 10.11 through 10.13 best-effort support.
| Platform | Version |
|---|---|
| Android | Android SDK 15 & below |
| iOS | iOS 10 & below and arm7v 32-bit iOS |
| Linux | Any 32-bit platform |
| macOS | Yosemite (10.10) & below |
| Windows | Windows Vista & below |
| Windows | Any 32-bit platform |
| 目标平台 | 目标架构 | 支持版本 | CI 测试版本 | 不支持版本 |
|---|---|---|---|---|
| Android SDK | x64, Arm32, Arm64 | 21 至 34 | 21 至 34 | 20 和更早版本 |
| iOS | Arm64 | 12 至 18 | 17 | 11 和更早版本 |
| macOS | x64, Arm64 | Mojave (10.14) 至 Sequoia (15) | Ventura (13), Sonoma (14) | High Sierra (10.13) 和更早版本 |
| Windows | x64, Arm64 | 10, 11 | 10 | 8 和更早版本 |
| Debian (Linux) | x64, Arm64 | 10, 11, 12 | 11, 12 | 9 和更早版本 |
| Ubuntu (Linux) | x64, Arm64 | 20.04 LTS 至 24.04 LTS | 20.04 LTS, 22.04 LTS | 23.10 和更早的非 LTS 版本 |
| Chrome (Web) | JavaScript, WebAssembly | 最新的 2 个 | 119, 125 | 95 和更早版本 |
| Firefox (Web) | JavaScript | 最新的 2 个 | 132 | 98 和更早版本 |
| Safari (Web) | JavaScript | 15.6 和更新版本 | 15.6 | 15.5 和更早版本 |
| Edge (Web) | JavaScript, WebAssembly | 最新的 2 个 | 119, 125 | 95 和更早版本 |
| 目标平台 | 目标架构 | 支持版本 | CI测试版本 | 不支持版本 |
|---|---|---|---|---|
| Android SDK | x64, Arm32, Arm64 | 21 to 34 | 21 to 34 | 20 and earlier |
| iOS | Arm64 | 12 to 18 | 17 | 11 and earlier |
| macOS | x64, Arm64 | Mojave (10.14) to Sequoia (15) | Ventura (13), Sonoma (14) | High Sierra (10.13) and earlier |
| Windows | x64, Arm64 | 10, 11 | 10 | 8 and earlier |
| Debian (Linux) | x64, Arm64 | 10, 11, 12 | 11, 12 | 9 and earlier |
| Ubuntu (Linux) | x64, Arm64 | 20.04 LTS to 24.04 LTS | 20.04 LTS, 22.04 LTS | 23.10 and earlier non-LTS |
| Chrome (Web) | JavaScript, WebAssembly | Latest 2 | 119, 125 | 95 and earlier |
| Firefox (Web) | JavaScript | Latest 2 | 132 | 98 and earlier |
| Safari (Web) | JavaScript | 15.6 and newer | 15.6 | 15.5 and earlier |
| Edge (Web) | JavaScript, WebAssembly | Latest 2 | 119, 125 | 95 and earlier |
BlowFish 是一个对称加密的加密算法。由 Bruce Schneier,1993年设计的。是一个免费自由使用的加密算法。
了解的必要知识
- BlowFish是一个对称区块加密算法。每次加密数据为 64位 (2个int)类型数据大小。八个字节
- BlowFish 密钥采用32-448位
- BlowFish是由一个16轮循环的Feistel结构进行加密的。
BlowFish 算法流程是由两部分组成 分别是密钥扩展以及数据加密
在数据加密中是一个16轮循环的Feistel网络。每一轮由一个密钥相关置换和一个密钥与数据相关的替换组成的。
先说一下BlowFish需要的子密钥。
BlowFish在加密或者初始化的过程中会使用两个盒来进行加密
分别是PBOX 以及SBOX
PBOX是 由18个32位的字的子密钥组成的。这些密钥可以通过预计算产生的。
其中PBOX记录的就是Π后面的小数位。转换成16进制存储到pBox中
例如:
|
1 2 3 4 |
p[0] = 0x243F6A88 P[1] = 0X85A308D3 P[2] = 0X13198A2E P[3] = 0X03707344 |
关于数学中Π大家应该知道。这里不再累赘。关于如何计算Π后面的小数位以及将小数位转为十六进制存储到p[0]---p[18] 这里也不再赘述。 因为这些都是预计算好的。我们直接使用就可以。
关于小数转为16进制可以使用网站进行转换(不确保以后还能否使用):小数转换16进制
例子如下:
Sbox跟PBOX一样也是Π的小数位组成。sBox是4组8*32的数组。 如下
|
1 |
s_box[4][256] = {{},{},{},{}}; |
pBox与Sbox就是BlowFish算法进行加密的核心置换表
如果想进行数据加密。那么我们就要进行子密钥生成。也就是要将我们的Key 与 pbox进行 异或
那么说一下流程吧
1.按顺序使用Π的小数部分初始化pbox与sbox (预先计算好了可以直接使用)
2.使用key参数得出key_pbox, 具体流程为 将pbox中的数据 与 key进行 ^ 然后设置到key_pbox中,轮询key每次取出四个字节来与pbox[i]进行 异或
如果Key不足的情况下 key从零开始补齐4个字节 继续与pbox[i]进行异或
例子:
|
1 2 3 4 5 6 |
伪代码: 设key为 “IBinary" key长度为:7 循环18次 key_pbox[0] = pbox[0] ^ (DWORD)"IBin" 使用4个字节存储 key_pbox[1] = pbox[1] ^ (DWORD)"aryI" 重新使用key的第一个字节补齐 key_pbox[17] = pbox[17] ^(DWORD)"xxxx" 一直到18轮 |
3.使用当前的key_pbox数组 与s_box数组对一个64位0数据进行加密。 也就是 两个int 类型数据 8个字节 输出的结果 重新修改到key_pbox 与 key_sbox中。
key_sbox就是当前的 使用s_box对64位数据进行加密,产生的输出修改的key_sbox中。
|
1 2 3 4 5 6 7 8 |
行循环4 列循环256 加密(data1,data2) key_sbox[0] = data1 key_sbox[1] = data2 第二轮循环 加密(data1,data2) key_sbox[2] = data1 key_sbox[2] = data2; |
一直循环直到修改完key_pbox与key_sbox为止
示例代码如下:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
#define N 16 //定义初始化需要用到的加密结构 typedef struct _BLOWFISH_CTX { //定义初始化的pbox 以及 sbox 在程序中进行初始化 unsigned int pbox[N + 2]; //总共18 unsigned int sbox[4][256]; }BLOWFISH_CTX,*PBLOWFISH_CTX; bool BlowFishInit(BLOWFISH_CTX* blowCtx, unsigned char * key, unsigned int keylen) { //第一步初始化Sbox的值 sbox是预先生成的。在全局区是 ORIG_S 数组 for (int Row = 0; Row < 4; Row++) { for (int Col = 0; Col < 256; Col++) { blowCtx->sbox[Row][Col] = ORIG_S[Row][Col]; } } /* 第二步 子密钥生成设置key_Pbox 设置pbox 1.循环18轮 2.每轮都设置ctx.pbox值与data ^ 3.data = *(DWORD*)key[0] key[1]..... data其实就是4字节转换的Ascii值 设key = "IBinary" data = "IBin" 类似于 memcpy(&data,"IBin",4); 当key不足的时候重新从头开始获取并且补足 */ int KeyIndex = 0; for (int index = 0; index < N + 2; index++) { unsigned int data = 0; //填充data 将key的字符设置到data当中 for (int k = 0; k < 4; k++) { //通过移位设置每个字符 data = (data << 8) | key[KeyIndex]; KeyIndex++; //如果超出了key长度 那么key要从开始 if (KeyIndex >= keylen) KeyIndex = 0; } //这是时设置key_pbox的值。 原理就是 pbox ^ data data就是我们的第二层循环。 就是获取四字节的key值 如果你的key只有四个字节。那么 //都可以不使用第二层循环了 blowCtx->pbox[index] = ORIG_P[index] ^ data; } /* 第三步 设置key_pbox 与 key_sbox的值 1.对一个64位0 进行加密。加密结果的输出设置到pbox[i]与pbox[i+1]中 2.初始化key_pbox之后继续重用Data1与Data2 继续进行加密设置到s_box中 */ unsigned int Data1 = 0; unsigned int Data2 = 0; for (int i = 0; i < N + 2; i+=2) { BlowFish_Encry(blowCtx, &Data1, &Data2); blowCtx->pbox[i] = Data1; blowCtx->pbox[i+1] = Data2; } //初始化Sbox for (int i = 0; i < 4; i++) { for (int j = 0; j < 256; j += 2) { BlowFish_Encry(blowCtx, &Data1, &Data2); blowCtx->sbox[i][j] = Data1; blowCtx->sbox[i][j + 1] = Data2; } } return true; } |
BlowFish加密很简单。就是 将一个数 拆分为 左右各32位数值 (也就是 8个字节 左边四个字节,右边四个字节) 然后 左边进行 ^ key_pbox 当作下一次循环的右边。 右边 则是 右边 ^ F(左边) 下次当作循环的左边。
循环16轮。
说着挺难。看下图:
简单的加密流程图:
在这里我们只看加密
|
1 2 3 4 5 |
原理就三行重要代码 循环16次 R = L ^ Key_pbox[i] L = F(R) ^ L swap(R,L); 最后一轮单独设置介绍完F之后继续说 |
这里不得不介绍下F函数。 F函数的输入是一个32位数 也就是四个字节类型数据。 然后内部就是将32位数进行拆分成abcd
例如:
|
1 2 3 4 5 6 7 |
data = 0x12345678 拆分后 a = 0x12 b = 0x34 c = 0x56 d = 0x78 |
拆分后的a b c d然后去Key_sbox中查表 然后取出对应的值。
公式如下:
|
1 2 3 4 5 6 7 8 |
((s1,a + s2,b) ^ s3,c) + s4,d 对应数组操作就是 value = key_sbox[0][a] + Key_sbox[1][b] value = value ^ key_sbox[2][c] Value = value + Key_sbox[3][d] 公式是从s1a s2b s3c s4d开始的。 数组下标是从0开始的。所以s1对应的就是 Key_sbox[0] 后面依次类推。 最后返回Value 公式简单记一下就是 return (((a + b) ^ c) + d) |
F函数明白了那么回头继续看一下加密操作。
图如下:
可以看到 首先计算 L ^Kr(Key_pbox[i]) 然后结果直接作为下一轮的右侧
右侧则是 经过论函数F 进行设置的。 最后变为下一轮循环的左侧。
R = R ^F(L)
最后一轮的话需要单独设置
|
1 2 |
R = R ^ Key_pbox[16] //数组中下标16就代表17 L = L ^ Key_pbox[17] //同上这里是代表下标18 |
其实加密函数就是循环16次。 然后每一轮都对 左侧32位 右侧32位进行操作。 操作之后直接作为下一轮循环的左右侧
核心代码如下:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
void BlowFish_Encry(PBLOWFISH_CTX blowCtx, unsigned int* left, unsigned int* right) { unsigned long Xl; unsigned long Xr; unsigned long temp; short i; //第一步 获取左右侧的数据 每组32位 Xl = *left; Xr = *right; //第二部进行16轮的加密 最后交换xl xr 作为下一轮循环的左右侧 for (i = 0; i < N; ++i) { Xl = Xl ^ blowCtx->pbox[i]; Xr = F(blowCtx, Xl) ^ Xr; temp = Xl; Xl = Xr; //交换左右的值。 l = R r= l 继续下一轮循环。总共16轮 Xr = temp; } //第三步 进行16轮循环之后我们需要特殊操作。 最后直接设置xr 与xr即可。 temp = Xl; Xl = Xr; //16轮完毕之后交换变量 Xr = temp; Xr = Xr ^ blowCtx->pbox[N]; //最后进行一次疑或 Xl = Xl ^ blowCtx->pbox[N + 1]; *left = Xl; *right = Xr; } |
至此我们的blowFish加密已经完成
解密与加密是相反操作。 加密的时候是从0开始遍历16轮 然后依次对xl xr进行操作。
解密的时候做事从16开始然后迭代16轮 对左右两侧做操作
最后16轮循环完毕之后还是进行一次^
代码如下:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
void BlowFish_Decrypt(PBLOWFISH_CTX blowCtx, unsigned int* left, unsigned int* right) { unsigned int Xl = *left; unsigned int Xr = *right; //倒着循环 for (int i = N + 1; i > 1; --i) { Xl = Xl ^ blowCtx->pbox[i]; Xr = Xr ^ F(blowCtx, Xl); //继续左右交换 unsigned int temp = Xl; Xl = Xr; Xr = temp; } //最后一轮继续交换 unsigned int temp = Xl; Xl = Xr; Xr = temp; //返还原 Xr = Xr ^ blowCtx->pbox[1]; Xl = Xl ^ blowCtx->pbox[0]; //设置变量返回 *left = Xl; *right = Xr; } |
至此解密完成
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 |
#pragma once /* 使用BlowFish进行加解密 */ //定义全局旧的pbox sbox 都是根据小数来的。 #define N 16 static const unsigned long ORIG_P[16 + 2] = { 0x243F6A88L, 0x85A308D3L, 0x13198A2EL, 0x03707344L, 0xA4093822L, 0x299F31D0L, 0x082EFA98L, 0xEC4E6C89L, 0x452821E6L, 0x38D01377L, 0xBE5466CFL, 0x34E90C6CL, 0xC0AC29B7L, 0xC97C50DDL, 0x3F84D5B5L, 0xB5470917L, 0x9216D5D9L, 0x8979FB1BL }; static const unsigned long ORIG_S[4][256] = { { 0xD1310BA6L, 0x98DFB5ACL, 0x2FFD72DBL, 0xD01ADFB7L, 0xB8E1AFEDL, 0x6A267E96L, 0xBA7C9045L, 0xF12C7F99L, 0x24A19947L, 0xB3916CF7L, 0x0801F2E2L, 0x858EFC16L, 0x636920D8L, 0x71574E69L, 0xA458FEA3L, 0xF4933D7EL, 0x0D95748FL, 0x728EB658L, 0x718BCD58L, 0x82154AEEL, 0x7B54A41DL, 0xC25A59B5L, 0x9C30D539L, 0x2AF26013L, 0xC5D1B023L, 0x286085F0L, 0xCA417918L, 0xB8DB38EFL, 0x8E79DCB0L, 0x603A180EL, 0x6C9E0E8BL, 0xB01E8A3EL, 0xD71577C1L, 0xBD314B27L, 0x78AF2FDAL, 0x55605C60L, 0xE65525F3L, 0xAA55AB94L, 0x57489862L, 0x63E81440L, 0x55CA396AL, 0x2AAB10B6L, 0xB4CC5C34L, 0x1141E8CEL, 0xA15486AFL, 0x7C72E993L, 0xB3EE1411L, 0x636FBC2AL, 0x2BA9C55DL, 0x741831F6L, 0xCE5C3E16L, 0x9B87931EL, 0xAFD6BA33L, 0x6C24CF5CL, 0x7A325381L, 0x28958677L, 0x3B8F4898L, 0x6B4BB9AFL, 0xC4BFE81BL, 0x66282193L, 0x61D809CCL, 0xFB21A991L, 0x487CAC60L, 0x5DEC8032L, 0xEF845D5DL, 0xE98575B1L, 0xDC262302L, 0xEB651B88L, 0x23893E81L, 0xD396ACC5L, 0x0F6D6FF3L, 0x83F44239L, 0x2E0B4482L, 0xA4842004L, 0x69C8F04AL, 0x9E1F9B5EL, 0x21C66842L, 0xF6E96C9AL, 0x670C9C61L, 0xABD388F0L, 0x6A51A0D2L, 0xD8542F68L, 0x960FA728L, 0xAB5133A3L, 0x6EEF0B6CL, 0x137A3BE4L, 0xBA3BF050L, 0x7EFB2A98L, 0xA1F1651DL, 0x39AF0176L, 0x66CA593EL, 0x82430E88L, 0x8CEE8619L, 0x456F9FB4L, 0x7D84A5C3L, 0x3B8B5EBEL, 0xE06F75D8L, 0x85C12073L, 0x401A449FL, 0x56C16AA6L, 0x4ED3AA62L, 0x363F7706L, 0x1BFEDF72L, 0x429B023DL, 0x37D0D724L, 0xD00A1248L, 0xDB0FEAD3L, 0x49F1C09BL, 0x075372C9L, 0x80991B7BL, 0x25D479D8L, 0xF6E8DEF7L, 0xE3FE501AL, 0xB6794C3BL, 0x976CE0BDL, 0x04C006BAL, 0xC1A94FB6L, 0x409F60C4L, 0x5E5C9EC2L, 0x196A2463L, 0x68FB6FAFL, 0x3E6C53B5L, 0x1339B2EBL, 0x3B52EC6FL, 0x6DFC511FL, 0x9B30952CL, 0xCC814544L, 0xAF5EBD09L, 0xBEE3D004L, 0xDE334AFDL, 0x660F2807L, 0x192E4BB3L, 0xC0CBA857L, 0x45C8740FL, 0xD20B5F39L, 0xB9D3FBDBL, 0x5579C0BDL, 0x1A60320AL, 0xD6A100C6L, 0x402C7279L, 0x679F25FEL, 0xFB1FA3CCL, 0x8EA5E9F8L, 0xDB3222F8L, 0x3C7516DFL, 0xFD616B15L, 0x2F501EC8L, 0xAD0552ABL, 0x323DB5FAL, 0xFD238760L, 0x53317B48L, 0x3E00DF82L, 0x9E5C57BBL, 0xCA6F8CA0L, 0x1A87562EL, 0xDF1769DBL, 0xD542A8F6L, 0x287EFFC3L, 0xAC6732C6L, 0x8C4F5573L, 0x695B27B0L, 0xBBCA58C8L, 0xE1FFA35DL, 0xB8F011A0L, 0x10FA3D98L, 0xFD2183B8L, 0x4AFCB56CL, 0x2DD1D35BL, 0x9A53E479L, 0xB6F84565L, 0xD28E49BCL, 0x4BFB9790L, 0xE1DDF2DAL, 0xA4CB7E33L, 0x62FB1341L, 0xCEE4C6E8L, 0xEF20CADAL, 0x36774C01L, 0xD07E9EFEL, 0x2BF11FB4L, 0x95DBDA4DL, 0xAE909198L, 0xEAAD8E71L, 0x6B93D5A0L, 0xD08ED1D0L, 0xAFC725E0L, 0x8E3C5B2FL, 0x8E7594B7L, 0x8FF6E2FBL, 0xF2122B64L, 0x8888B812L, 0x900DF01CL, 0x4FAD5EA0L, 0x688FC31CL, 0xD1CFF191L, 0xB3A8C1ADL, 0x2F2F2218L, 0xBE0E1777L, 0xEA752DFEL, 0x8B021FA1L, 0xE5A0CC0FL, 0xB56F74E8L, 0x18ACF3D6L, 0xCE89E299L, 0xB4A84FE0L, 0xFD13E0B7L, 0x7CC43B81L, 0xD2ADA8D9L, 0x165FA266L, 0x80957705L, 0x93CC7314L, 0x211A1477L, 0xE6AD2065L, 0x77B5FA86L, 0xC75442F5L, 0xFB9D35CFL, 0xEBCDAF0CL, 0x7B3E89A0L, 0xD6411BD3L, 0xAE1E7E49L, 0x00250E2DL, 0x2071B35EL, 0x226800BBL, 0x57B8E0AFL, 0x2464369BL, 0xF009B91EL, 0x5563911DL, 0x59DFA6AAL, 0x78C14389L, 0xD95A537FL, 0x207D5BA2L, 0x02E5B9C5L, 0x83260376L, 0x6295CFA9L, 0x11C81968L, 0x4E734A41L, 0xB3472DCAL, 0x7B14A94AL, 0x1B510052L, 0x9A532915L, 0xD60F573FL, 0xBC9BC6E4L, 0x2B60A476L, 0x81E67400L, 0x08BA6FB5L, 0x571BE91FL, 0xF296EC6BL, 0x2A0DD915L, 0xB6636521L, 0xE7B9F9B6L, 0xFF34052EL, 0xC5855664L, 0x53B02D5DL, 0xA99F8FA1L, 0x08BA4799L, 0x6E85076AL }, { 0x4B7A70E9L, 0xB5B32944L, 0xDB75092EL, 0xC4192623L, 0xAD6EA6B0L, 0x49A7DF7DL, 0x9CEE60B8L, 0x8FEDB266L, 0xECAA8C71L, 0x699A17FFL, 0x5664526CL, 0xC2B19EE1L, 0x193602A5L, 0x75094C29L, 0xA0591340L, 0xE4183A3EL, 0x3F54989AL, 0x5B429D65L, 0x6B8FE4D6L, 0x99F73FD6L, 0xA1D29C07L, 0xEFE830F5L, 0x4D2D38E6L, 0xF0255DC1L, 0x4CDD2086L, 0x8470EB26L, 0x6382E9C6L, 0x021ECC5EL, 0x09686B3FL, 0x3EBAEFC9L, 0x3C971814L, 0x6B6A70A1L, 0x687F3584L, 0x52A0E286L, 0xB79C5305L, 0xAA500737L, 0x3E07841CL, 0x7FDEAE5CL, 0x8E7D44ECL, 0x5716F2B8L, 0xB03ADA37L, 0xF0500C0DL, 0xF01C1F04L, 0x0200B3FFL, 0xAE0CF51AL, 0x3CB574B2L, 0x25837A58L, 0xDC0921BDL, 0xD19113F9L, 0x7CA92FF6L, 0x94324773L, 0x22F54701L, 0x3AE5E581L, 0x37C2DADCL, 0xC8B57634L, 0x9AF3DDA7L, 0xA9446146L, 0x0FD0030EL, 0xECC8C73EL, 0xA4751E41L, 0xE238CD99L, 0x3BEA0E2FL, 0x3280BBA1L, 0x183EB331L, 0x4E548B38L, 0x4F6DB908L, 0x6F420D03L, 0xF60A04BFL, 0x2CB81290L, 0x24977C79L, 0x5679B072L, 0xBCAF89AFL, 0xDE9A771FL, 0xD9930810L, 0xB38BAE12L, 0xDCCF3F2EL, 0x5512721FL, 0x2E6B7124L, 0x501ADDE6L, 0x9F84CD87L, 0x7A584718L, 0x7408DA17L, 0xBC9F9ABCL, 0xE94B7D8CL, 0xEC7AEC3AL, 0xDB851DFAL, 0x63094366L, 0xC464C3D2L, 0xEF1C1847L, 0x3215D908L, 0xDD433B37L, 0x24C2BA16L, 0x12A14D43L, 0x2A65C451L, 0x50940002L, 0x133AE4DDL, 0x71DFF89EL, 0x10314E55L, 0x81AC77D6L, 0x5F11199BL, 0x043556F1L, 0xD7A3C76BL, 0x3C11183BL, 0x5924A509L, 0xF28FE6EDL, 0x97F1FBFAL, 0x9EBABF2CL, 0x1E153C6EL, 0x86E34570L, 0xEAE96FB1L, 0x860E5E0AL, 0x5A3E2AB3L, 0x771FE71CL, 0x4E3D06FAL, 0x2965DCB9L, 0x99E71D0FL, 0x803E89D6L, 0x5266C825L, 0x2E4CC978L, 0x9C10B36AL, 0xC6150EBAL, 0x94E2EA78L, 0xA5FC3C53L, 0x1E0A2DF4L, 0xF2F74EA7L, 0x361D2B3DL, 0x1939260FL, 0x19C27960L, 0x5223A708L, 0xF71312B6L, 0xEBADFE6EL, 0xEAC31F66L, 0xE3BC4595L, 0xA67BC883L, 0xB17F37D1L, 0x018CFF28L, 0xC332DDEFL, 0xBE6C5AA5L, 0x65582185L, 0x68AB9802L, 0xEECEA50FL, 0xDB2F953BL, 0x2AEF7DADL, 0x5B6E2F84L, 0x1521B628L, 0x29076170L, 0xECDD4775L, 0x619F1510L, 0x13CCA830L, 0xEB61BD96L, 0x0334FE1EL, 0xAA0363CFL, 0xB5735C90L, 0x4C70A239L, 0xD59E9E0BL, 0xCBAADE14L, 0xEECC86BCL, 0x60622CA7L, 0x9CAB5CABL, 0xB2F3846EL, 0x648B1EAFL, 0x19BDF0CAL, 0xA02369B9L, 0x655ABB50L, 0x40685A32L, 0x3C2AB4B3L, 0x319EE9D5L, 0xC021B8F7L, 0x9B540B19L, 0x875FA099L, 0x95F7997EL, 0x623D7DA8L, 0xF837889AL, 0x97E32D77L, 0x11ED935FL, 0x16681281L, 0x0E358829L, 0xC7E61FD6L, 0x96DEDFA1L, 0x7858BA99L, 0x57F584A5L, 0x1B227263L, 0x9B83C3FFL, 0x1AC24696L, 0xCDB30AEBL, 0x532E3054L, 0x8FD948E4L, 0x6DBC3128L, 0x58EBF2EFL, 0x34C6FFEAL, 0xFE28ED61L, 0xEE7C3C73L, 0x5D4A14D9L, 0xE864B7E3L, 0x42105D14L, 0x203E13E0L, 0x45EEE2B6L, 0xA3AAABEAL, 0xDB6C4F15L, 0xFACB4FD0L, 0xC742F442L, 0xEF6ABBB5L, 0x654F3B1DL, 0x41CD2105L, 0xD81E799EL, 0x86854DC7L, 0xE44B476AL, 0x3D816250L, 0xCF62A1F2L, 0x5B8D2646L, 0xFC8883A0L, 0xC1C7B6A3L, 0x7F1524C3L, 0x69CB7492L, 0x47848A0BL, 0x5692B285L, 0x095BBF00L, 0xAD19489DL, 0x1462B174L, 0x23820E00L, 0x58428D2AL, 0x0C55F5EAL, 0x1DADF43EL, 0x233F7061L, 0x3372F092L, 0x8D937E41L, 0xD65FECF1L, 0x6C223BDBL, 0x7CDE3759L, 0xCBEE7460L, 0x4085F2A7L, 0xCE77326EL, 0xA6078084L, 0x19F8509EL, 0xE8EFD855L, 0x61D99735L, 0xA969A7AAL, 0xC50C06C2L, 0x5A04ABFCL, 0x800BCADCL, 0x9E447A2EL, 0xC3453484L, 0xFDD56705L, 0x0E1E9EC9L, 0xDB73DBD3L, 0x105588CDL, 0x675FDA79L, 0xE3674340L, 0xC5C43465L, 0x713E38D8L, 0x3D28F89EL, 0xF16DFF20L, 0x153E21E7L, 0x8FB03D4AL, 0xE6E39F2BL, 0xDB83ADF7L }, { 0xE93D5A68L, 0x948140F7L, 0xF64C261CL, 0x94692934L, 0x411520F7L, 0x7602D4F7L, 0xBCF46B2EL, 0xD4A20068L, 0xD4082471L, 0x3320F46AL, 0x43B7D4B7L, 0x500061AFL, 0x1E39F62EL, 0x97244546L, 0x14214F74L, 0xBF8B8840L, 0x4D95FC1DL, 0x96B591AFL, 0x70F4DDD3L, 0x66A02F45L, 0xBFBC09ECL, 0x03BD9785L, 0x7FAC6DD0L, 0x31CB8504L, 0x96EB27B3L, 0x55FD3941L, 0xDA2547E6L, 0xABCA0A9AL, 0x28507825L, 0x530429F4L, 0x0A2C86DAL, 0xE9B66DFBL, 0x68DC1462L, 0xD7486900L, 0x680EC0A4L, 0x27A18DEEL, 0x4F3FFEA2L, 0xE887AD8CL, 0xB58CE006L, 0x7AF4D6B6L, 0xAACE1E7CL, 0xD3375FECL, 0xCE78A399L, 0x406B2A42L, 0x20FE9E35L, 0xD9F385B9L, 0xEE39D7ABL, 0x3B124E8BL, 0x1DC9FAF7L, 0x4B6D1856L, 0x26A36631L, 0xEAE397B2L, 0x3A6EFA74L, 0xDD5B4332L, 0x6841E7F7L, 0xCA7820FBL, 0xFB0AF54EL, 0xD8FEB397L, 0x454056ACL, 0xBA489527L, 0x55533A3AL, 0x20838D87L, 0xFE6BA9B7L, 0xD096954BL, 0x55A867BCL, 0xA1159A58L, 0xCCA92963L, 0x99E1DB33L, 0xA62A4A56L, 0x3F3125F9L, 0x5EF47E1CL, 0x9029317CL, 0xFDF8E802L, 0x04272F70L, 0x80BB155CL, 0x05282CE3L, 0x95C11548L, 0xE4C66D22L, 0x48C1133FL, 0xC70F86DCL, 0x07F9C9EEL, 0x41041F0FL, 0x404779A4L, 0x5D886E17L, 0x325F51EBL, 0xD59BC0D1L, 0xF2BCC18FL, 0x41113564L, 0x257B7834L, 0x602A9C60L, 0xDFF8E8A3L, 0x1F636C1BL, 0x0E12B4C2L, 0x02E1329EL, 0xAF664FD1L, 0xCAD18115L, 0x6B2395E0L, 0x333E92E1L, 0x3B240B62L, 0xEEBEB922L, 0x85B2A20EL, 0xE6BA0D99L, 0xDE720C8CL, 0x2DA2F728L, 0xD0127845L, 0x95B794FDL, 0x647D0862L, 0xE7CCF5F0L, 0x5449A36FL, 0x877D48FAL, 0xC39DFD27L, 0xF33E8D1EL, 0x0A476341L, 0x992EFF74L, 0x3A6F6EABL, 0xF4F8FD37L, 0xA812DC60L, 0xA1EBDDF8L, 0x991BE14CL, 0xDB6E6B0DL, 0xC67B5510L, 0x6D672C37L, 0x2765D43BL, 0xDCD0E804L, 0xF1290DC7L, 0xCC00FFA3L, 0xB5390F92L, 0x690FED0BL, 0x667B9FFBL, 0xCEDB7D9CL, 0xA091CF0BL, 0xD9155EA3L, 0xBB132F88L, 0x515BAD24L, 0x7B9479BFL, 0x763BD6EBL, 0x37392EB3L, 0xCC115979L, 0x8026E297L, 0xF42E312DL, 0x6842ADA7L, 0xC66A2B3BL, 0x12754CCCL, 0x782EF11CL, 0x6A124237L, 0xB79251E7L, 0x06A1BBE6L, 0x4BFB6350L, 0x1A6B1018L, 0x11CAEDFAL, 0x3D25BDD8L, 0xE2E1C3C9L, 0x44421659L, 0x0A121386L, 0xD90CEC6EL, 0xD5ABEA2AL, 0x64AF674EL, 0xDA86A85FL, 0xBEBFE988L, 0x64E4C3FEL, 0x9DBC8057L, 0xF0F7C086L, 0x60787BF8L, 0x6003604DL, 0xD1FD8346L, 0xF6381FB0L, 0x7745AE04L, 0xD736FCCCL, 0x83426B33L, 0xF01EAB71L, 0xB0804187L, 0x3C005E5FL, 0x77A057BEL, 0xBDE8AE24L, 0x55464299L, 0xBF582E61L, 0x4E58F48FL, 0xF2DDFDA2L, 0xF474EF38L, 0x8789BDC2L, 0x5366F9C3L, 0xC8B38E74L, 0xB475F255L, 0x46FCD9B9L, 0x7AEB2661L, 0x8B1DDF84L, 0x846A0E79L, 0x915F95E2L, 0x466E598EL, 0x20B45770L, 0x8CD55591L, 0xC902DE4CL, 0xB90BACE1L, 0xBB8205D0L, 0x11A86248L, 0x7574A99EL, 0xB77F19B6L, 0xE0A9DC09L, 0x662D09A1L, 0xC4324633L, 0xE85A1F02L, 0x09F0BE8CL, 0x4A99A025L, 0x1D6EFE10L, 0x1AB93D1DL, 0x0BA5A4DFL, 0xA186F20FL, 0x2868F169L, 0xDCB7DA83L, 0x573906FEL, 0xA1E2CE9BL, 0x4FCD7F52L, 0x50115E01L, 0xA70683FAL, 0xA002B5C4L, 0x0DE6D027L, 0x9AF88C27L, 0x773F8641L, 0xC3604C06L, 0x61A806B5L, 0xF0177A28L, 0xC0F586E0L, 0x006058AAL, 0x30DC7D62L, 0x11E69ED7L, 0x2338EA63L, 0x53C2DD94L, 0xC2C21634L, 0xBBCBEE56L, 0x90BCB6DEL, 0xEBFC7DA1L, 0xCE591D76L, 0x6F05E409L, 0x4B7C0188L, 0x39720A3DL, 0x7C927C24L, 0x86E3725FL, 0x724D9DB9L, 0x1AC15BB4L, 0xD39EB8FCL, 0xED545578L, 0x08FCA5B5L, 0xD83D7CD3L, 0x4DAD0FC4L, 0x1E50EF5EL, 0xB161E6F8L, 0xA28514D9L, 0x6C51133CL, 0x6FD5C7E7L, 0x56E14EC4L, 0x362ABFCEL, 0xDDC6C837L, 0xD79A3234L, 0x92638212L, 0x670EFA8EL, 0x406000E0L }, { 0x3A39CE37L, 0xD3FAF5CFL, 0xABC27737L, 0x5AC52D1BL, 0x5CB0679EL, 0x4FA33742L, 0xD3822740L, 0x99BC9BBEL, 0xD5118E9DL, 0xBF0F7315L, 0xD62D1C7EL, 0xC700C47BL, 0xB78C1B6BL, 0x21A19045L, 0xB26EB1BEL, 0x6A366EB4L, 0x5748AB2FL, 0xBC946E79L, 0xC6A376D2L, 0x6549C2C8L, 0x530FF8EEL, 0x468DDE7DL, 0xD5730A1DL, 0x4CD04DC6L, 0x2939BBDBL, 0xA9BA4650L, 0xAC9526E8L, 0xBE5EE304L, 0xA1FAD5F0L, 0x6A2D519AL, 0x63EF8CE2L, 0x9A86EE22L, 0xC089C2B8L, 0x43242EF6L, 0xA51E03AAL, 0x9CF2D0A4L, 0x83C061BAL, 0x9BE96A4DL, 0x8FE51550L, 0xBA645BD6L, 0x2826A2F9L, 0xA73A3AE1L, 0x4BA99586L, 0xEF5562E9L, 0xC72FEFD3L, 0xF752F7DAL, 0x3F046F69L, 0x77FA0A59L, 0x80E4A915L, 0x87B08601L, 0x9B09E6ADL, 0x3B3EE593L, 0xE990FD5AL, 0x9E34D797L, 0x2CF0B7D9L, 0x022B8B51L, 0x96D5AC3AL, 0x017DA67DL, 0xD1CF3ED6L, 0x7C7D2D28L, 0x1F9F25CFL, 0xADF2B89BL, 0x5AD6B472L, 0x5A88F54CL, 0xE029AC71L, 0xE019A5E6L, 0x47B0ACFDL, 0xED93FA9BL, 0xE8D3C48DL, 0x283B57CCL, 0xF8D56629L, 0x79132E28L, 0x785F0191L, 0xED756055L, 0xF7960E44L, 0xE3D35E8CL, 0x15056DD4L, 0x88F46DBAL, 0x03A16125L, 0x0564F0BDL, 0xC3EB9E15L, 0x3C9057A2L, 0x97271AECL, 0xA93A072AL, 0x1B3F6D9BL, 0x1E6321F5L, 0xF59C66FBL, 0x26DCF319L, 0x7533D928L, 0xB155FDF5L, 0x03563482L, 0x8ABA3CBBL, 0x28517711L, 0xC20AD9F8L, 0xABCC5167L, 0xCCAD925FL, 0x4DE81751L, 0x3830DC8EL, 0x379D5862L, 0x9320F991L, 0xEA7A90C2L, 0xFB3E7BCEL, 0x5121CE64L, 0x774FBE32L, 0xA8B6E37EL, 0xC3293D46L, 0x48DE5369L, 0x6413E680L, 0xA2AE0810L, 0xDD6DB224L, 0x69852DFDL, 0x09072166L, 0xB39A460AL, 0x6445C0DDL, 0x586CDECFL, 0x1C20C8AEL, 0x5BBEF7DDL, 0x1B588D40L, 0xCCD2017FL, 0x6BB4E3BBL, 0xDDA26A7EL, 0x3A59FF45L, 0x3E350A44L, 0xBCB4CDD5L, 0x72EACEA8L, 0xFA6484BBL, 0x8D6612AEL, 0xBF3C6F47L, 0xD29BE463L, 0x542F5D9EL, 0xAEC2771BL, 0xF64E6370L, 0x740E0D8DL, 0xE75B1357L, 0xF8721671L, 0xAF537D5DL, 0x4040CB08L, 0x4EB4E2CCL, 0x34D2466AL, 0x0115AF84L, 0xE1B00428L, 0x95983A1DL, 0x06B89FB4L, 0xCE6EA048L, 0x6F3F3B82L, 0x3520AB82L, 0x011A1D4BL, 0x277227F8L, 0x611560B1L, 0xE7933FDCL, 0xBB3A792BL, 0x344525BDL, 0xA08839E1L, 0x51CE794BL, 0x2F32C9B7L, 0xA01FBAC9L, 0xE01CC87EL, 0xBCC7D1F6L, 0xCF0111C3L, 0xA1E8AAC7L, 0x1A908749L, 0xD44FBD9AL, 0xD0DADECBL, 0xD50ADA38L, 0x0339C32AL, 0xC6913667L, 0x8DF9317CL, 0xE0B12B4FL, 0xF79E59B7L, 0x43F5BB3AL, 0xF2D519FFL, 0x27D9459CL, 0xBF97222CL, 0x15E6FC2AL, 0x0F91FC71L, 0x9B941525L, 0xFAE59361L, 0xCEB69CEBL, 0xC2A86459L, 0x12BAA8D1L, 0xB6C1075EL, 0xE3056A0CL, 0x10D25065L, 0xCB03A442L, 0xE0EC6E0EL, 0x1698DB3BL, 0x4C98A0BEL, 0x3278E964L, 0x9F1F9532L, 0xE0D392DFL, 0xD3A0342BL, 0x8971F21EL, 0x1B0A7441L, 0x4BA3348CL, 0xC5BE7120L, 0xC37632D8L, 0xDF359F8DL, 0x9B992F2EL, 0xE60B6F47L, 0x0FE3F11DL, 0xE54CDA54L, 0x1EDAD891L, 0xCE6279CFL, 0xCD3E7E6FL, 0x1618B166L, 0xFD2C1D05L, 0x848FD2C5L, 0xF6FB2299L, 0xF523F357L, 0xA6327623L, 0x93A83531L, 0x56CCCD02L, 0xACF08162L, 0x5A75EBB5L, 0x6E163697L, 0x88D273CCL, 0xDE966292L, 0x81B949D0L, 0x4C50901BL, 0x71C65614L, 0xE6C6C7BDL, 0x327A140AL, 0x45E1D006L, 0xC3F27B9AL, 0xC9AA53FDL, 0x62A80F00L, 0xBB25BFE2L, 0x35BDD2F6L, 0x71126905L, 0xB2040222L, 0xB6CBCF7CL, 0xCD769C2BL, 0x53113EC0L, 0x1640E3D3L, 0x38ABBD60L, 0x2547ADF0L, 0xBA38209CL, 0xF746CE76L, 0x77AFA1C5L, 0x20756060L, 0x85CBFE4EL, 0x8AE88DD8L, 0x7AAAF9B0L, 0x4CF9AA7EL, 0x1948C25CL, 0x02FB8A8CL, 0x01C36AE4L, 0xD6EBE1F9L, 0x90D4F869L, 0xA65CDEA0L, 0x3F09252DL, 0xC208E69FL, 0xB74E6132L, 0xCE77E25BL, 0x578FDFE3L, 0x3AC372E6L } }; #define N 16 //定义初始化需要用到的加密结构 typedef struct _BLOWFISH_CTX { //定义初始化的pbox 以及 sbox 在程序中进行初始化 unsigned int pbox[N + 2]; //总共18 unsigned int sbox[4][256]; }BLOWFISH_CTX,*PBLOWFISH_CTX; /* 初始化函数 此函数功能如下 1.接受key 与 keylen参数(当然keylen)可以自己计算 2.初始化sbox 将全局的sbox的内容复制到CTX中的sbox中 3.初始化pbox pbox的初始化方法如下 1.迭代18论。然后每一轮都设置CTX的pbox 2.CTX.pbox需要使用全局pbox ^ data 3.data是一个四字节整数。其中存储的就是key的四个字节。 key = "12345678abc" 每一轮中 data = "1234" data = "5678" data = "abc1" //注意这里当超出keylen的时候。 data获取的key要从0开始 。。。。 */ bool BlowFishInit(BLOWFISH_CTX* blowCtx, unsigned char*key, unsigned int keylen); /* F函数 F函数是将一个32位数分别进行拆分。 拆分为四组。 每一组都作为sbox的索引值 然后进行下列运算 ((s1[a] + s2[b]) ^ s3[c]) + s4[d] 在编程中sbox是数组是从零开始。 所以s1 对应s[0] s2对应s[1] 在编程中总结下公式: temap = s[0][a] + s[1][b] teamp = temp ^ s[2][c]' temp = temp + s[3][d] 简单的记住就是 ((a+b) ^ c)+d; 当然每个都对应下标为 0 1 2 3 s[0][a] s[1][b] s[2][c] s[3][d] 最后返回结果值 return temp */ static unsigned long F(BLOWFISH_CTX* ctx, unsigned long x); //signed int F(PBLOWFISH_CTX blowCtx,unsigned int Data); /* 加密函数: 首次用在初始化中是对一个64位0进行加密。 一次加密八个字节 核心思想为 加密左边与右边数据 左边数据直接 ^ PBOX 右边数据 = 右边数据 ^ f(左边数据) 然后进行交换。 以上是16轮的交换 剩下一轮则是 左边 = 左边^PBOX[N+1] 右边 = 右边^pbox[N] 最后设置相关数值 */ void BlowFish_Encry(PBLOWFISH_CTX blowCtx, unsigned int* left, unsigned int* right); /* 跟加密一样。只不过结果相反步骤如下: 首先遍历从最后一轮开始逐次递减 最后一轮数据 右边= 右边^PBOX[1] 左边数据 = 左边数据 ^pbox[0] */ void BlowFish_Decrypt(PBLOWFISH_CTX blowCtx, unsigned int* left, unsigned int* right); |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
#include "BlowFish.h" #include <string> using namespace std; bool BlowFishInit(BLOWFISH_CTX* blowCtx, unsigned char * key, unsigned int keylen) { //设置传入的CTX中的SBOX值 for (int Row = 0; Row < 4; Row++) { for (int Col = 0; Col < 256; Col++) { blowCtx->sbox[Row][Col] = ORIG_S[Row][Col]; } } /* 设置pbox 1.循环18轮 2.每轮都设置ctx.pbox值与data ^ 3.data = *(DWORD*)key[0] key[1]..... */ int KeyIndex = 0; for (int index = 0; index < N + 2; index++) { unsigned int data = 0; //填充data 将key的字符设置到data当中 for (int k = 0; k < 4; k++) { //通过移位设置每个字符 data = (data << 8) | key[KeyIndex]; KeyIndex++; //如果超出了key长度 那么key要从开始 if (KeyIndex >= keylen) KeyIndex = 0; } //否则不满足 blowCtx->pbox[index] = ORIG_P[index] ^ data; } //对一个64位0 进行加密。加密结果的输出设置到pbox[i]与pbox[i+1]中 unsigned int Data1 = 0; unsigned int Data2 = 0; for (int i = 0; i < N + 2; i+=2) { BlowFish_Encry(blowCtx, &Data1, &Data2); blowCtx->pbox[i] = Data1; blowCtx->pbox[i+1] = Data2; } //初始化Sbox for (int i = 0; i < 4; i++) { for (int j = 0; j < 256; j += 2) { BlowFish_Encry(blowCtx, &Data1, &Data2); blowCtx->sbox[i][j] = Data1; blowCtx->sbox[i][j + 1] = Data2; } } return true; } //unsigned int F(PBLOWFISH_CTX blowCtx, unsigned int Data) //{ // // unsigned int a, b, c, d; // /* // 利用位运算 取出下标值 // */ // // a = (Data >> 24) & 0xFF; // b = (Data >> 16) & 0xFF; // c = (Data >> 8) & 0xFf; // d = Data & 0xFF; // // // int TempValue = blowCtx->sbox[0][a] + blowCtx->sbox[1][b]; // TempValue = TempValue ^ blowCtx->sbox[2][c]; // TempValue = TempValue + blowCtx->sbox[3][d]; // //公式 ((a+b)^c)+d // return TempValue; //} static unsigned long F(BLOWFISH_CTX* ctx, unsigned long x) { unsigned short a, b, c, d; unsigned long y; /* d = (unsigned short)(x & 0xFF); x >>= 8; c = (unsigned short)(x & 0xFF); x >>= 8; b = (unsigned short)(x & 0xFF); x >>= 8; a = (unsigned short)(x & 0xFF); //都可以使用 */ a = (x >> 24) & 0xFF; b = (x >> 16) & 0xFF; c = (x >> 8) & 0xFf; d = x & 0xFF; y = ctx->sbox[0][a] + ctx->sbox[1][b]; y = y ^ ctx->sbox[2][c]; y = y + ctx->sbox[3][d]; return y; } void BlowFish_Encry(PBLOWFISH_CTX blowCtx, unsigned int* left, unsigned int* right) { unsigned long Xl; unsigned long Xr; unsigned long temp; short i; //加密部分首先将其分为left跟right两组。 每一组分别32位 Xl = *left; Xr = *right; for (i = 0; i < N; ++i) { Xl = Xl ^ blowCtx->pbox[i]; Xr = F(blowCtx, Xl) ^ Xr; temp = Xl; Xl = Xr; //交换左右的值。 l = R r= l 继续下一轮循环。总共16轮 Xr = temp; } temp = Xl; Xl = Xr; //16轮完毕之后交换变量 Xr = temp; Xr = Xr ^ blowCtx->pbox[N]; //最后进行一次疑或 Xl = Xl ^ blowCtx->pbox[N + 1]; *left = Xl; *right = Xr; } void BlowFish_Decrypt(PBLOWFISH_CTX blowCtx, unsigned int* left, unsigned int* right) { unsigned int Xl = *left; unsigned int Xr = *right; //倒着循环 for (int i = N + 1; i > 1; --i) { Xl = Xl ^ blowCtx->pbox[i]; Xr = Xr ^ F(blowCtx, Xl); //继续左右交换 unsigned int temp = Xl; Xl = Xr; Xr = temp; } //最后一轮继续交换 unsigned int temp = Xl; Xl = Xr; Xr = temp; //返还原 Xr = Xr ^ blowCtx->pbox[1]; Xl = Xl ^ blowCtx->pbox[0]; //设置变量返回 *left = Xl; *right = Xr; } int main() { unsigned int L = 1, R = 2; BLOWFISH_CTX ctx; BlowFishInit(&ctx,(unsigned char*)"IBinary",strlen("IBinary")); BlowFish_Encry(&ctx, &L, &R); BlowFish_Decrypt(&ctx, &L, &R); } |
经过测试加解密输出结果是对的。
直接从 Flutter API 官方页面(Form Class Documentation)复制 Form 示例,并使用 Flutter 的 Web 调试模式运行。
尝试用鼠标单击文本输入时,遇到以下错误:
|
1 2 3 4 5 6 7 8 9 10 11 12 |
DartError: Assertion failed: org-dartlang-sdk:///lib/_engine/engine/pointer_binding/event_position_helper.dart:70:10 targetElement == domElement "The targeted input element must be the active input element" dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 288:3 throw_ dart-sdk/lib/_internal/js_dev_runtime/private/profile.dart 110:39 assertFailed dart-sdk/lib/_internal/js_dev_runtime/private/profile.dart 110:39 _computeOffsetForInputs lib/_engine/engine/pointer_binding/event_position_helper.dart 38:14 computeEventOffsetToTarget lib/_engine/engine/pointer_binding.dart 1088:30 [_convertEventsToPointerData] lib/_engine/engine/pointer_binding.dart 1016:9 <fn> lib/_engine/engine/pointer_binding.dart 948:7 <fn> lib/_engine/engine/pointer_binding.dart 541:9 loggedHandler dart-sdk/lib/_internal/js_dev_runtime/patch/js_allow_interop_patch.dart 212:27 _callDartFunctionFast1 |
这个问题是 Flutter 3.27.0 / 3.27.1 / 3.27.2 的缺陷,官方已经在 Flutter 3.27.3 / 3.28 版本修复,后续升级到 Flutter 3.27.3 / 3.28 即可解决此问题。
目前(2024/12/23) master 通道已经修复这个问题,可以通过切换到 master 通道来解决:
|
1 |
$ flutter channel master |
目前(2025/01/25) Flutter 3.27.3 已经修复这个问题,升级到此版本可以修复问题。
Windows 11 每次开机都会弹出下图所示的信息:
经过查找是罗技鼠标驱动的问题,驱动卸载之后,系统重启还是会弹对话框。
具体做法是:
1. 运行、输入 regedit
2. 找到 HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run 目录下的 Logitech Download Assistant
3. 右键删除即可