
Vue项目使用默认的8080端口正常启动,可在启动命令指定了80端口后,竟然莫名其妙的在1024端口启动,多次尝试依然在1024端口,我以为是系统80端口被占用,查看了一下并没有。
但是Docker的Nginx服务器是可以正常使用的。


查资料说MacOS的1024以下端口使用需要root权限,试了一下确实可以用。

另外,如果80端口被占用,会使用下一个端口81,而不是1024.

Vue项目使用默认的8080端口正常启动,可在启动命令指定了80端口后,竟然莫名其妙的在1024端口启动,多次尝试依然在1024端口,我以为是系统80端口被占用,查看了一下并没有。
但是Docker的Nginx服务器是可以正常使用的。
查资料说MacOS的1024以下端口使用需要root权限,试了一下确实可以用。
另外,如果80端口被占用,会使用下一个端口81,而不是1024.
不知道最近怎么回事,Docker镜像下载不下来,Maven依赖也下载不下来,手动下载一个jar文件安装到仓库。
mvn install:install-file -Dfile=jar包的路径 -DgroupId=gruopId中的内容 -DartifactId=actifactId的内容 -Dversion=version的内容 -Dpackaging=jar
如:
➜ ~ mvn install:install-file -Dfile=/Users/admin/Downloads/mybatis-plus-generator-3.3.2.jar -DgroupId=com.baomidou -DartifactId=mybatis-plus-generator -Dversion=3.3.2 -Dpackaging=jar
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------< org.apache.maven:standalone-pom >-------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] --------------------------------[ pom ]---------------------------------
[INFO]
[INFO] --- maven-install-plugin:2.4:install-file (default-cli) @ standalone-pom ---
[INFO] Installing /Users/admin/Downloads/mybatis-plus-generator-3.3.2.jar to /Users/admin/.m2/repository/com/baomidou/mybatis-plus-generator/3.3.2/mybatis-plus-generator-3.3.2.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.169 s
[INFO] Finished at: 2022-11-02T21:07:44+08:00
[INFO] ------------------------------------------------------------------------
查看网站的接口时为了方便可以使用Postman的Interceptor功能,它可以直接捕获浏览器的请求和Cookie等信息,顺利的使用这个功能需要完成几个部分的安装:
安装前两项的时候没有什么问题,Interceptor Bridge 在Linux和Win系统上也很顺利,但在Mac系统上需要自己安装Node环境。
我确信自己一定在系统安装了Node,但是多次打开Postman软件依然让我下载Node,于是我去Postman官网看到这样一段话:
If you’re on Windows or Linux, Postman will take care of everything for you. If you’re on macOS, you’ll be prompted to install NodeJS if it’s not already installed on your computer. If the option to download doesn’t appear, you can manually download and install with the following links: macOS, Linux, or Windows.
于是我开始手动安装Interceptor Bridge ,却发现还有没有用。于是继续看网站,下面有这样一段描述:
If you are unable to use the integration after completing the guided installation, you’ll want to ? check the following items:
- [macOS] Node is properly installed – Node is installed and available at /usr/local/node or /usr/local/bin/node, or you have the environment variable NVM_BIN set.
原来是这样,Postman判断系统是否安装Node的依据是/usr/local/node
或/usr/local/bin/node
目录下是否存在Node安装文件,而不是环境变量,我的Node为了能统一管理是使用Mac系统的包管理器Homebrew安装的,它的目录在/opt/homebrew/opt/node@14/bin/node
,这也是我在其他地方能正常使用Node命令,Postman找不到Node的根本原因。
于是我考虑解决方法,我可以把Homebrew版的Node卸载,使用安装包方式安装,我确信它会出现在/usr/local/node
或/usr/local/bin/node
目录下,但我不想这样,于是我做了一个链接(link):
ln /opt/homebrew/opt/node@14/bin/node /usr/local/bin/node
于是问题解决了。
包管理工具解决了软件统一安装,版本控制等问题,但也存在其他问题,守恒定律体现在各个地方,提升了便捷性的同时也降低了通用性,这种解决方法的问题是,在更换Node版本或者其他改动的时候,链接会失效。希望失效的时候系统给我一个友好的报错,让我能准确的定位问题,不然我只能在这里找到答案了。
public static void main(String[] args) {
int result = m();
System.out.println(result);
}
private static int m() {
int i = 100;
try {
return i;
} finally {
i++;
}
}
}
IntelliJ IDEA反编译的结果:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package com.example.exception;
public class ExceptionTest15 {
public ExceptionTest15() {
}
public static void main(String[] args) {
int result = m();
System.out.println(result);
}
private static int m() {
byte i = 100;
byte var1;
try {
var1 = i;
} finally {
int var5 = i + 1;
}
return var1;
}
}
jad反编译的结果:
// jadx decompiler
public class ExceptionTest15 {
public static void main(String[] args) {
int result = m();
System.out.println(result);
}
private static int m() {
try {
int i = 100 + 1;
return 100;
} catch (Throwable th) {
int i2 = 100 + 1;
throw th;
}
}
}
public static void main(String[] args) {
int result = m();
System.out.println(result); // 100
}
/*
* 结果是 100
* Java语法规则(有一些规则是不能破坏的)
* Java中有这样一条规则:
* Java方法体中的代码必须是自上而下顺序依次逐行执行。
* Java中还有这样一条规则:
* return语句一旦执行,整个方法就执行结束。
* */
private static int m() {
int i = 100;
try {
// 这行代码出现在int = 100;的下面,所以最终结果一定是100。
// return必须保证最后执行。一旦执行,整个方法结束。
return i;
} finally {
i++;
}
}
}
Mysql:1055 - Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated
sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'
-- 导出表结构
SELECT A.TABLE_SCHEMA,
A.TABLE_NAME,
A.TABLE_COMMENT
FROM INFORMATION_SCHEMA.TABLES A
WHERE A.TABLE_SCHEMA = '$table_name';
解压后的文件夹中有3个文件:
在Apache安装目录中新建cert目录,并将解压的Apache证书、证书链文件和密钥文件拷贝到cert目录中。如果需要安装多个证书,需在Apache目录中新建对应数量的cert目录,用于存放不同的证书 。
说明 如果申请证书时选择了手动创建CSR文件,请将手动生成创建的密钥文件拷贝到cert目录中并命名为domain name.key。
在Apache安装目录下,打开Apache/conf/httpd.conf文件,并找到以下参数,按照下文中注释内容进行配置。
#LoadModule ssl_module modules/mod_ssl.so #删除行首的配置语句注释符号“#”加载mod_ssl.so模块启用SSL服务,Apache默认是不启用该模块的。 #Include conf/extra/httpd-ssl.conf #删除行首的配置语句注释符号“#”。
说明 如果您在httpd.conf文件中没有找到以上配置语句,请确认您的Apache服务器中是否已经安装mod_ssl.so模块。可执行yum install -y mod_ssl
命令安装mod_ssl模块。
保存httpd.conf文件并退出。
打开Apache/conf/extra/httpd-ssl.conf文件并找到以下参数,按照下文中注释内容进行配置。
注意:根据操作系统的不同,http-ssl.conf文件也可能存放在conf.d/ssl.conf目录中。
<VirtualHost *:443>
ServerName #修改为申请证书时绑定的域名www.YourDomainName1.com。
DocumentRoot /data/www/hbappserver/public
SSLEngine on
SSLProtocol all -SSLv2 -SSLv3 # 添加SSL协议支持协议,去掉不安全的协议。
SSLCipherSuite HIGH:!RC4:!MD5:!aNULL:!eNULL:!NULL:!DH:!EDH:!EXP:+MEDIUM # 修改加密套件。
SSLHonorCipherOrder on
SSLCertificateFile cert/domain name1_public.crt # 将domain name1_public.crt替换成您证书文件名。
SSLCertificateKeyFile cert/domain name1.key # 将domain name1.key替换成您证书的密钥文件名。
SSLCertificateChainFile cert/domain name1_chain.crt # 将domain name1_chain.crt替换成您证书的密钥文件名;证书链开头如果有#字符,请删除。
</VirtualHost>
#如果证书包含多个域名,复制以上参数,并将ServerName替换成第二个域名。
<VirtualHost *:443>
ServerName #修改为申请证书时绑定的第二个域名www.YourDomainName2.com。
DocumentRoot /data/www/hbappserver/public
SSLEngine on
SSLProtocol all -SSLv2 -SSLv3 # 添加SSL协议支持协议,去掉不安全的协议。
SSLCipherSuite HIGH:!RC4:!MD5:!aNULL:!eNULL:!NULL:!DH:!EDH:!EXP:+MEDIUM # 修改加密套件。
SSLHonorCipherOrder on
SSLCertificateFile cert/domain name2_public.crt # 将domain name2替换成您申请证书时的第二个域名。
SSLCertificateKeyFile cert/domain name2.key # 将domain name2替换成您申请证书时的第二个域名。
SSLCertificateChainFile cert/domain name2_chain.crt # 将domain name2替换成您申请证书时的第二个域名;证书链开头如果有#字符,请删除。
</VirtualHost>
说明 需注意您的浏览器版本是否支持SNI功能。如果不支持,多域名证书配置将无法生效。
保存httpd-ssl.conf文件并退出。
在Apache的bin目录下执行以下命令:
1、停止Apache服务。
systemctl stop httpd
2、开启Apache服务。
systemctl start httpd
在httpd.conf文件中的中间,添加以下重定向代码。
RewriteEngine on
RewriteCond %{SERVER_PORT} !^443$
RewriteRule ^(.*)$ https://%{SERVER_NAME}$1 [L,R]
证书安装完成后,您可通过登录证书的绑定域名验证该证书是否安装成功。
https://domain name #domain name替换成证书绑定的域名。
如果网页地址栏出现小锁标志,表示证书安装成功。
<?php
namespace FatSmallTools;
class NavicatPassword
{
protected $version = 0;
protected $aesKey = 'libcckeylibcckey';
protected $aesIv = 'libcciv libcciv ';
protected $blowString = '3DC5CA39';
protected $blowKey = null;
protected $blowIv = null;
public function __construct($version = 12)
{
$this->version = $version;
$this->blowKey = sha1('3DC5CA39', true);
$this->blowIv = hex2bin('d9c7c3c8870d64bd');
}
public function encrypt($string)
{
$result = FALSE;
switch ($this->version) {
case 11:
$result = $this->encryptEleven($string);
break;
case 12:
$result = $this->encryptTwelve($string);
break;
default:
break;
}
return $result;
}
protected function encryptEleven($string)
{
$round = intval(floor(strlen($string) / 8));
$leftLength = strlen($string) % 8;
$result = '';
$currentVector = $this->blowIv;
for ($i = 0; $i < $round; $i ) {
$temp = $this->encryptBlock($this->xorBytes(substr($string, 8 * $i, 8), $currentVector));
$currentVector = $this->xorBytes($currentVector, $temp);
$result .= $temp;
}
if ($leftLength) {
$currentVector = $this->encryptBlock($currentVector);
$result .= $this->xorBytes(substr($string, 8 * $i, $leftLength), $currentVector);
}
return strtoupper(bin2hex($result));
}
protected function encryptBlock($block)
{
return openssl_encrypt($block, 'BF-ECB', $this->blowKey, OPENSSL_RAW_DATA|OPENSSL_NO_PADDING);
}
protected function decryptBlock($block)
{
return openssl_decrypt($block, 'BF-ECB', $this->blowKey, OPENSSL_RAW_DATA|OPENSSL_NO_PADDING);
}
protected function xorBytes($str1, $str2)
{
$result = '';
for ($i = 0; $i < strlen($str1); $i ) {
$result .= chr(ord($str1[$i]) ^ ord($str2[$i]));
}
return $result;
}
protected function encryptTwelve($string)
{
$result = openssl_encrypt($string, 'AES-128-CBC', $this->aesKey, OPENSSL_RAW_DATA, $this->aesIv);
return strtoupper(bin2hex($result));
}
public function decrypt($string)
{
$result = FALSE;
switch ($this->version) {
case 11:
$result = $this->decryptEleven($string);
break;
case 12:
$result = $this->decryptTwelve($string);
break;
default:
break;
}
return $result;
}
protected function decryptEleven($upperString)
{
$string = hex2bin(strtolower($upperString));
$round = intval(floor(strlen($string) / 8));
$leftLength = strlen($string) % 8;
$result = '';
$currentVector = $this->blowIv;
for ($i = 0; $i < $round; $i ) {
$encryptedBlock = substr($string, 8 * $i, 8);
$temp = $this->xorBytes($this->decryptBlock($encryptedBlock), $currentVector);
$currentVector = $this->xorBytes($currentVector, $encryptedBlock);
$result .= $temp;
}
if ($leftLength) {
$currentVector = $this->encryptBlock($currentVector);
$result .= $this->xorBytes(substr($string, 8 * $i, $leftLength), $currentVector);
}
return $result;
}
protected function decryptTwelve($upperString)
{
$string = hex2bin(strtolower($upperString));
return openssl_decrypt($string, 'AES-128-CBC', $this->aesKey, OPENSSL_RAW_DATA, $this->aesIv);
}
}
use FatSmallToolsNavicatPassword;
//需要指定版本,11或12
$navicatPassword = new NavicatPassword(12);
//$navicatPassword = new NavicatPassword(11);
//解密
//$decode = $navicatPassword->decrypt('15057D7BA390');
$decode = $navicatPassword->decrypt('BD24FE2CDBD24FE2CDAA36A18B4AA36A18B4');
echo $decode."n";
注意代码需要修改一下使用。
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
import java.util.Arrays;
/**
* 以下程序均为ChatGPT生成
* @Author: 木芒果
*/
public class NavicatPassword {
public static void main(String[] args) throws Exception {
NavicatPassword navicatPassword = new NavicatPassword();
// 解密11版本及以前的密码
//String decode = navicatPassword.decrypt("15057D7BA390", 11);
// 解密12版本及以后的密码
//String decode = navicatPassword.decrypt("15057D7BA390", 12);
String decode = navicatPassword.decrypt("解密密码", 12);
System.out.println(decode);
}
private static final String AES_KEY = "libcckeylibcckey";
private static final String AES_IV = "libcciv libcciv ";
private static final String BLOW_KEY = "3DC5CA39";
private static final String BLOW_IV = "d9c7c3c8870d64bd";
public static String encrypt(String plaintext, int version) throws Exception {
switch (version) {
case 11:
return encryptEleven(plaintext);
case 12:
return encryptTwelve(plaintext);
default:
throw new IllegalArgumentException("Unsupported version");
}
}
public static String decrypt(String ciphertext, int version) throws Exception {
switch (version) {
case 11:
return decryptEleven(ciphertext);
case 12:
return decryptTwelve(ciphertext);
default:
throw new IllegalArgumentException("Unsupported version");
}
}
private static String encryptEleven(String plaintext) throws Exception {
byte[] iv = hexStringToByteArray(BLOW_IV);
byte[] key = hashToBytes(BLOW_KEY);
int round = plaintext.length() / 8;
int leftLength = plaintext.length() % 8;
StringBuilder result = new StringBuilder();
byte[] currentVector = iv.clone();
Cipher cipher = Cipher.getInstance("Blowfish/ECB/NoPadding");
SecretKeySpec secretKeySpec = new SecretKeySpec(key, "Blowfish");
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
for (int i = 0; i < round; i++) {
byte[] block = xorBytes(plaintext.substring(i * 8, (i + 1) * 8).getBytes(), currentVector);
byte[] temp = cipher.doFinal(block);
currentVector = xorBytes(currentVector, temp);
result.append(bytesToHex(temp));
}
if (leftLength > 0) {
currentVector = cipher.doFinal(currentVector);
byte[] block = xorBytes(plaintext.substring(round * 8).getBytes(), currentVector);
result.append(bytesToHex(block));
}
return result.toString().toUpperCase();
}
private static String encryptTwelve(String plaintext) throws Exception {
byte[] iv = AES_IV.getBytes();
byte[] key = AES_KEY.getBytes();
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
byte[] result = cipher.doFinal(plaintext.getBytes());
return bytesToHex(result).toUpperCase();
}
private static String decryptEleven(String ciphertext) throws Exception {
byte[] iv = hexStringToByteArray(BLOW_IV);
byte[] key = hashToBytes(BLOW_KEY);
byte[] encrypted = hexStringToByteArray(ciphertext.toLowerCase());
int round = encrypted.length / 8;
int leftLength = encrypted.length % 8;
StringBuilder result = new StringBuilder();
byte[] currentVector = iv.clone();
Cipher cipher = Cipher.getInstance("Blowfish/ECB/NoPadding");
SecretKeySpec secretKeySpec = new SecretKeySpec(key, "Blowfish");
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
for (int i = 0; i < round; i++) {
byte[] block = Arrays.copyOfRange(encrypted, i * 8, (i + 1) * 8);
byte[] temp = xorBytes(cipher.doFinal(block), currentVector);
currentVector = xorBytes(currentVector, block);
result.append(new String(temp));
}
if (leftLength > 0) {
currentVector = cipher.doFinal(currentVector);
byte[] block = Arrays.copyOfRange(encrypted, round * 8, round * 8 + leftLength);
result.append(new String(xorBytes(block, currentVector)));
}
return result.toString();
}
private static String decryptTwelve(String ciphertext) throws Exception {
byte[] iv = AES_IV.getBytes();
byte[] key = AES_KEY.getBytes();
byte[] encrypted = hexStringToByteArray(ciphertext.toLowerCase());
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
byte[] result = cipher.doFinal(encrypted);
return new String(result);
}
private static byte[] xorBytes(byte[] bytes1, byte[] bytes2) {
byte[] result = new byte[bytes1.length];
for (int i = 0; i < bytes1.length; i++) {
result[i] = (byte) (bytes1[i] ^ bytes2[i]);
}
return result;
}
private static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i + 1), 16));
}
return data;
}
private static byte[] hashToBytes(String s) throws Exception {
return MessageDigest.getInstance("SHA-1").digest(s.getBytes());
}
private static String bytesToHex(byte[] bytes) {
StringBuilder result = new StringBuilder();
for (byte b : bytes) {
result.append(String.format("%02X", b));
}
return result.toString();
}
}
意外将hosts文件删除,将恢复方法记录
版本信息: Windows 10 专业版 1909
将C:\Windows\System32\drivers\etc\
目录下的lmhosts.sam
文件复制一份并重命名为hosts
即可。
安装markdown-preview插件后,使用时无论是使用快捷键还是命令,都没有任何反馈
在vim命令行输入messages
输出以下出错信息( 部分):
......
[vim-node-rpc] rpc error: internal/modules/cjs/loader.js:883
[vim-node-rpc] rpc error: throw err;
[vim-node-rpc] rpc error: ^
[vim-node-rpc] rpc error:
[vim-node-rpc] rpc error: error: cannot find module 'tslib'
[vim-node-rpc] rpc error: require stack:
[vim-node-rpc] rpc error: - /users/dxm/.vim/bundle/markdown-preview.nvim/app/lib/app/index.js
[vim-node-rpc] rpc error: - /users/dxm/.vim/bundle/markdown-preview.nvim/app/index.js
......
可以看到是因为缺少tslib模块引起的错误,经查资料得知此模块用途超出我的知识范围qaq,
tslib是一个开源的程序,能够为触摸屏驱动获得的采样提供诸如滤波、去抖、校准等功能。-百度百科
所以去插件的Github仓库去碰碰运气,终于在一条issue下找到解决方法:
在插件目录下执行:
npm install
其他操作系统或许可以尝试诸如yarn install
等操作,当然,还是要根据出错信息 自己排查解决。