-
Notifications
You must be signed in to change notification settings - Fork 2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #550 from Zhuoyuan1/main
Navicat链接导入
- Loading branch information
Showing
14 changed files
with
870 additions
and
45 deletions.
There are no files selected for viewing
82 changes: 82 additions & 0 deletions
82
...r-web-api/src/main/java/ai/chat2db/server/web/api/controller/ncx/ConverterController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
package ai.chat2db.server.web.api.controller.ncx; | ||
|
||
import ai.chat2db.server.tools.base.wrapper.result.DataResult; | ||
import ai.chat2db.server.tools.common.util.ConfigUtils; | ||
import ai.chat2db.server.web.api.controller.ncx.service.ConverterService; | ||
import ai.chat2db.server.web.api.controller.ncx.vo.UploadVO; | ||
import ai.chat2db.server.web.api.util.FileUtils; | ||
import lombok.SneakyThrows; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.web.bind.annotation.PostMapping; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RequestParam; | ||
import org.springframework.web.bind.annotation.RestController; | ||
import org.springframework.web.multipart.MultipartFile; | ||
|
||
import java.io.File; | ||
import java.util.Objects; | ||
import java.util.UUID; | ||
|
||
/** | ||
* ConverterController | ||
* | ||
* @author lzy | ||
**/ | ||
@RequestMapping("/api/converter") | ||
@RestController | ||
@Slf4j | ||
public class ConverterController { | ||
|
||
@Autowired | ||
private ConverterService converterService; | ||
|
||
/** | ||
* 导出教程 | ||
* | ||
* @param file file | ||
* @return DataResult<UploadVO> | ||
* @see <a href="https://blog.csdn.net/kkk123445/article/details/122514124?spm=1001.2014.3001.5502" /> | ||
**/ | ||
@SneakyThrows | ||
@PostMapping("/ncx/upload") | ||
public DataResult<UploadVO> ncxUploadFile(@RequestParam("file") MultipartFile file) { | ||
// 验证文件后缀 | ||
String fileExtension = FileUtils.getFileExtension(Objects.requireNonNull(file.getOriginalFilename())); | ||
if (!fileExtension.equalsIgnoreCase(FileUtils.ConfigFile.NCX.name())) { | ||
return DataResult.error("1", "上传的文件必须是ncx文件!"); | ||
} | ||
File temp = new File(ConfigUtils.CONFIG_BASE_PATH + File.separator + UUID.randomUUID() + ".tmp"); | ||
file.transferTo(temp); | ||
return DataResult.of(converterService.uploadFile(temp)); | ||
} | ||
|
||
@SneakyThrows | ||
@PostMapping("/dbp/upload") | ||
public DataResult<UploadVO> dbpUploadFile(@RequestParam("file") MultipartFile file) { | ||
// 验证文件后缀 | ||
String fileExtension = FileUtils.getFileExtension(Objects.requireNonNull(file.getOriginalFilename())); | ||
if (!fileExtension.equalsIgnoreCase(FileUtils.ConfigFile.DBP.name())) { | ||
return DataResult.error("1", "上传的文件必须是ncx文件!"); | ||
} | ||
File temp = new File(ConfigUtils.CONFIG_BASE_PATH + File.separator + UUID.randomUUID() + ".tmp"); | ||
file.transferTo(temp); | ||
return DataResult.of(converterService.dbpUploadFile(temp)); | ||
} | ||
|
||
|
||
/** | ||
* 导入datagrip的连接信息,通过 ctrl/cmd + c(shift多选)复制连接,再导入进来 | ||
* 目前复制的连接信息里面是没有密码的、ssh连接信息也没有 | ||
* | ||
* @param text text | ||
* @return DataResult<UploadVO> | ||
**/ | ||
@SneakyThrows | ||
@PostMapping("/datagrip/upload") | ||
public DataResult<UploadVO> datagripUploadFile(@RequestParam("text") String text) { | ||
return DataResult.of(converterService.datagripUploadFile(text)); | ||
} | ||
|
||
|
||
} |
44 changes: 44 additions & 0 deletions
44
...r-web-api/src/main/java/ai/chat2db/server/web/api/controller/ncx/cipher/CommonCipher.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package ai.chat2db.server.web.api.controller.ncx.cipher; | ||
|
||
import java.util.Formatter; | ||
|
||
/** | ||
* CommonCipher 公共加/解密 | ||
* | ||
* @author lzy | ||
*/ | ||
public abstract class CommonCipher { | ||
|
||
public String encryptString(String plaintext) { | ||
return null; | ||
} | ||
|
||
public String decryptString(String ciphertext) { | ||
return null; | ||
} | ||
|
||
public String printHexBinary(byte[] data) { | ||
StringBuilder hexBuilder = new StringBuilder(); | ||
Formatter formatter = new Formatter(hexBuilder); | ||
for (byte b : data) { | ||
formatter.format("%02x", b); | ||
} | ||
return hexBuilder.toString(); | ||
} | ||
|
||
public static byte[] parseHexBinary(String data) { | ||
return hexStringToByteArray(data); | ||
} | ||
|
||
public static byte[] hexStringToByteArray(String hex) { | ||
if (hex.length() % 2 != 0) { | ||
throw new IllegalArgumentException("Hex string length must be even"); | ||
} | ||
byte[] bytes = new byte[hex.length() / 2]; | ||
for (int i = 0; i < hex.length(); i += 2) { | ||
String byteString = hex.substring(i, i + 2); | ||
bytes[i / 2] = (byte) Integer.parseInt(byteString, 16); | ||
} | ||
return bytes; | ||
} | ||
} |
177 changes: 177 additions & 0 deletions
177
...eb-api/src/main/java/ai/chat2db/server/web/api/controller/ncx/cipher/Navicat11Cipher.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,177 @@ | ||
package ai.chat2db.server.web.api.controller.ncx.cipher; | ||
|
||
import org.apache.commons.lang3.StringUtils; | ||
|
||
import javax.crypto.Cipher; | ||
import javax.crypto.spec.SecretKeySpec; | ||
import java.nio.charset.StandardCharsets; | ||
import java.security.MessageDigest; | ||
import java.util.Arrays; | ||
|
||
/** | ||
* Navicat11及以下密码加密解密 | ||
* | ||
* @author lzy | ||
*/ | ||
public class Navicat11Cipher extends CommonCipher { | ||
public static final String DefaultUserKey = "3DC5CA39"; | ||
private static byte[] IV; | ||
|
||
private static SecretKeySpec key; | ||
private static Cipher encryptor; | ||
private static Cipher decrypt; | ||
|
||
private static void initKey() { | ||
try { | ||
MessageDigest sha1 = MessageDigest.getInstance("SHA1"); | ||
byte[] userKey_data = Navicat11Cipher.DefaultUserKey.getBytes(StandardCharsets.UTF_8); | ||
sha1.update(userKey_data, 0, userKey_data.length); | ||
key = new SecretKeySpec(sha1.digest(), "Blowfish"); | ||
} catch (Exception e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
|
||
private static void initCipherEncrypt() { | ||
try { | ||
// Must use NoPadding | ||
encryptor = Cipher.getInstance("Blowfish/ECB/NoPadding"); | ||
encryptor.init(Cipher.ENCRYPT_MODE, key); | ||
} catch (Exception e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
|
||
private static void initCipherDecrypt() { | ||
try { | ||
// Must use NoPadding | ||
decrypt = Cipher.getInstance("Blowfish/ECB/NoPadding"); | ||
decrypt.init(Cipher.DECRYPT_MODE, key); | ||
} catch (Exception e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
|
||
private static void initIV() { | ||
try { | ||
byte[] initVec = parseHexBinary("FFFFFFFFFFFFFFFF"); | ||
IV = encryptor.doFinal(initVec); | ||
} catch (Exception e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
|
||
private void xorBytes(byte[] a, byte[] b) { | ||
for (int i = 0; i < a.length; i++) { | ||
int aVal = a[i] & 0xff; // convert byte to integer | ||
int bVal = b[i] & 0xff; | ||
a[i] = (byte) (aVal ^ bVal); // xor aVal and bVal and typecast to byte | ||
} | ||
} | ||
|
||
private void xorBytes(byte[] a, byte[] b, int l) { | ||
for (int i = 0; i < l; i++) { | ||
int aVal = a[i] & 0xff; // convert byte to integer | ||
int bVal = b[i] & 0xff; | ||
a[i] = (byte) (aVal ^ bVal); // xor aVal and bVal and typecast to byte | ||
} | ||
} | ||
|
||
static { | ||
initKey(); | ||
initCipherEncrypt(); | ||
initCipherDecrypt(); | ||
initIV(); | ||
} | ||
|
||
private byte[] Encrypt(byte[] inData) { | ||
try { | ||
byte[] CV = Arrays.copyOf(IV, IV.length); | ||
byte[] ret = new byte[inData.length]; | ||
|
||
int blocks_len = inData.length / 8; | ||
int left_len = inData.length % 8; | ||
|
||
for (int i = 0; i < blocks_len; i++) { | ||
byte[] temp = Arrays.copyOfRange(inData, i * 8, (i * 8) + 8); | ||
|
||
xorBytes(temp, CV); | ||
temp = encryptor.doFinal(temp); | ||
xorBytes(CV, temp); | ||
|
||
System.arraycopy(temp, 0, ret, i * 8, 8); | ||
} | ||
|
||
if (left_len != 0) { | ||
CV = encryptor.doFinal(CV); | ||
byte[] temp = Arrays.copyOfRange(inData, blocks_len * 8, (blocks_len * 8) + left_len); | ||
xorBytes(temp, CV, left_len); | ||
System.arraycopy(temp, 0, ret, blocks_len * 8, temp.length); | ||
} | ||
|
||
return ret; | ||
} catch (Exception e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
|
||
@Override | ||
public String encryptString(String inputString) { | ||
try { | ||
byte[] inData = inputString.getBytes(StandardCharsets.UTF_8); | ||
byte[] outData = Encrypt(inData); | ||
return printHexBinary(outData); | ||
} catch (Exception e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
|
||
private byte[] Decrypt(byte[] inData) { | ||
try { | ||
byte[] cv = Arrays.copyOf(IV, IV.length); | ||
byte[] ret = new byte[inData.length]; | ||
|
||
int blocks_len = inData.length / 8; | ||
int left_len = inData.length % 8; | ||
|
||
for (int i = 0; i < blocks_len; i++) { | ||
byte[] temp = Arrays.copyOfRange(inData, i * 8, (i * 8) + 8); | ||
|
||
temp = decrypt.doFinal(temp); | ||
xorBytes(temp, cv); | ||
System.arraycopy(temp, 0, ret, i * 8, 8); | ||
for (int j = 0; j < cv.length; j++) { | ||
cv[j] = (byte) (cv[j] ^ inData[i * 8 + j]); | ||
} | ||
} | ||
|
||
if (left_len != 0) { | ||
cv = encryptor.doFinal(cv); | ||
byte[] temp = Arrays.copyOfRange(inData, blocks_len * 8, (blocks_len * 8) + left_len); | ||
|
||
xorBytes(temp, cv, left_len); | ||
for (int j = 0; j < temp.length; j++) { | ||
ret[blocks_len * 8 + j] = temp[j]; | ||
} | ||
} | ||
|
||
return ret; | ||
} catch (Exception e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
|
||
@Override | ||
public String decryptString(String hexString) { | ||
if (StringUtils.isEmpty(hexString)) { | ||
return ""; | ||
} | ||
try { | ||
byte[] inData = parseHexBinary(hexString); | ||
byte[] outData = Decrypt(inData); | ||
return new String(outData, StandardCharsets.UTF_8); | ||
} catch (Exception e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
} |
50 changes: 50 additions & 0 deletions
50
...eb-api/src/main/java/ai/chat2db/server/web/api/controller/ncx/cipher/Navicat12Cipher.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package ai.chat2db.server.web.api.controller.ncx.cipher; | ||
|
||
import org.apache.commons.lang3.StringUtils; | ||
|
||
import javax.crypto.Cipher; | ||
import javax.crypto.spec.IvParameterSpec; | ||
import javax.crypto.spec.SecretKeySpec; | ||
import java.nio.charset.StandardCharsets; | ||
|
||
/** | ||
* Navicat12及以上密码加密解密 | ||
* | ||
* @author lzy | ||
*/ | ||
public class Navicat12Cipher extends CommonCipher { | ||
private static final SecretKeySpec AES_KEY; | ||
private static final IvParameterSpec AES_IV; | ||
|
||
static { | ||
AES_KEY = new SecretKeySpec("libcckeylibcckey".getBytes(StandardCharsets.UTF_8), "AES"); | ||
AES_IV = new IvParameterSpec("libcciv libcciv ".getBytes(StandardCharsets.UTF_8)); | ||
} | ||
|
||
@Override | ||
public String encryptString(String plaintext) { | ||
try { | ||
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); | ||
cipher.init(Cipher.ENCRYPT_MODE, AES_KEY, AES_IV); | ||
byte[] ret = cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8)); | ||
return printHexBinary(ret); | ||
} catch (Exception e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
|
||
@Override | ||
public String decryptString(String ciphertext) { | ||
if (StringUtils.isEmpty(ciphertext)) { | ||
return ""; | ||
} | ||
try { | ||
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); | ||
cipher.init(Cipher.DECRYPT_MODE, AES_KEY, AES_IV); | ||
byte[] ret = cipher.doFinal(parseHexBinary(ciphertext)); | ||
return new String(ret, StandardCharsets.UTF_8); | ||
} catch (Exception e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
} |
Oops, something went wrong.