Flutter文本处理插件precis的使用

Flutter文本处理插件precis的使用

PRECIS 插件是一个 Dart 实现,用于根据应用协议准备、强制执行和比较国际化字符串。该插件是基于 rocks.xmpp.precis 项目的端口实现。它主要处理用户名、密码和其他国际化字符串的安全问题。

关于

PRECIS 验证并准备Unicode字符串,使其可以在应用协议中安全使用。例如,在处理用户名和密码时,如果这些字符串被用于身份验证和授权决策,那么如果实体提供的字符串被错误地连接到其他账户或在线资源上,应用程序的安全性可能会受到威胁。PRECIS 可以解决这类问题。

该库支持以下规范:

  • RFC 8264:PRECIS Framework
  • RFC 8265:PRECIS 表示用户名和密码的准备、强制执行和比较
  • RFC 8266:PRECIS 表示昵称的准备、强制执行和比较

PRECIS 废弃了 Stringprep(RFC 3454)。

使用

对于大多数用例,只需选择包中的一个现有配置文件,然后准备或强制执行字符串即可。

import 'package:precis/precis.dart' as precis;

final profile1 = precis.usernameCaseMapped;
final profile2 = precis.usernameCasePreserved;
final profile3 = precis.opaqueString;
final profile4 = precis.nickname;

如果你觉得冒险,可以扩展抽象类 PrecisProfile 并定义自己的自定义配置文件。但是,这在 RFC 8264 中是不推荐的。

准备

准备确保允许字符,但通常不会应用任何映射规则。以下代码会抛出异常,因为字符串包含了一个不允许的字符(Unicode 类别 Lt)。

precis.usernameCaseMapped.prepare('\u01C5'); // Capital Letter D with Small Letter Z with Caron

抛出的异常通常是 InvalidCodePointException,它会给开发者提供关于哪个字符无效的信息。所有其他异常都会扩展 PrecisException 以便于处理。

强制执行

强制执行会对字符串应用一组规则,将其转换为规范形式,以便进行字符串比较。

final enforced = precis.usernameCaseMapped.enforce("UpperCaseUsernmae"); // => uppercaseusername

强制执行不仅仅是上述的小写映射。它还会将模糊字符映射为其明确的形式。以下示例将所有字符映射为 Latin Small Letter A with Ring Above(U+00E5)。

final ang = precis.usernameCaseMapped.enforce('\u212B'); // Angstrom Sign
final a = precis.usernameCaseMapped.enforce('\u0041\u030A'); // Latin Capital A + Combining Ring Above
final aRing = precis.usernameCaseMapped.enforce('\u00C5'); // Latin Capital A with Ring Above
// ang == a => true
// a == aRing => true

如果字符串包含禁止的代码点,则会抛出 InvalidCodePointException,就像在准备过程中一样。

比较

你可以使用 PrecisProfile.toComparableString(String) 来检查两个字符串是否相等:

final profile = precis.usernameCaseMapped;
if (profile.toComparableString('foobar') == profile.toComparableString('FooBar')) {
    // 用户名已存在
}

或者你可以使用 PrecisProfile.compare 作为 Comparator

if (profile.compare("foobar", "FooBar") == 0) {
    // 用户名已存在
}

注意:配置文件在比较时可能使用与强制执行不同的规则(如昵称配置文件,RFC 8266)。

完整示例代码

以下是在实际项目中如何使用 precis 插件的完整示例代码:

// Copyright (c) 2022, Brian Armstrong. All rights reserved. Use of this source code
// is governed by a BSD-style license that can be found in the LICENSE file.

import 'package:precis/precis.dart' as precis;

/// 验证 [username] 是否包含无效字符。
/// 返回应用了一些基本规则的字符串
/// 失败时抛出 [InvalidCodePointException]
String validateUsername(String username) {
  return precis.usernameCaseMapped.prepare(username);
}

/// 格式化用户名以进行重复检查,并验证 [username] 是否包含无效字符
/// 返回应用了所有规则的格式化字符串
/// 如果有无效字符则抛出 [InvalidCodePointException]
/// 如果有无效的LTR和RTL字符混合则抛出 [InvalidDirectionalityException]
/// 如果出现其他错误(如空字符串)则抛出 [EnforcementException]
String formatUsernameForDuplicateCheck(String username) {
  return precis.usernameCaseMapped.enforce(username);
}

/// 验证给定的密码是否相同。这在更改密码时非常有用。
/// 此方法对两个字符串都强制执行所有规则,因此可能会抛出上述三种异常之一。
bool passwordsMatch(String password1, String password2) {
  return precis.opaqueString.compare(password1, password2) == 0;
}

更多关于Flutter文本处理插件precis的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter文本处理插件precis的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在处理Flutter中的文本时,precis 插件可以用于生成文本的摘要或预览。尽管 precis 并不是 Flutter 官方或广泛认知的标准库,但我们可以假设它是一个用于文本摘要的第三方库。由于具体的 precis 库细节可能因版本和实现而异,以下是一个假设性的示例,展示如何在 Flutter 项目中使用一个类似的文本摘要插件。

首先,确保在 pubspec.yaml 文件中添加了对该插件的依赖(请注意,这里的 precis 是假设性的,实际使用时需要替换为真实的包名):

dependencies:
  flutter:
    sdk: flutter
  precis: ^x.y.z  # 替换为实际的版本号

然后,运行 flutter pub get 来获取依赖。

接下来,在 Dart 代码中导入并使用该插件。以下是一个示例,展示如何使用假设的 precis 插件来生成文本摘要:

import 'package:flutter/material.dart';
import 'package:precis/precis.dart';  // 假设这是插件的导入路径

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Text Precis Example'),
        ),
        body: Center(
          child: TextPrecisExample(),
        ),
      ),
    );
  }
}

class TextPrecisExample extends StatefulWidget {
  @override
  _TextPrecisExampleState createState() => _TextPrecisExampleState();
}

class _TextPrecisExampleState extends State<TextPrecisExample> {
  String? originalText;
  String? precisText;

  @override
  void initState() {
    super.initState();
    // 示例文本
    originalText = 'Flutter is an open-source UI software development kit created by Google. It is used for developing applications for Android, iOS, Linux, macOS, Windows, and the web from a single codebase.';
    // 生成摘要(假设precis函数接受文本和字数限制作为参数)
    precisText = generatePrecis(originalText!, maxLength: 50);
  }

  // 假设的 generatePrecis 函数,实际使用时需根据插件文档实现
  String generatePrecis(String text, {required int maxLength}) {
    // 这里仅作为示例,实际插件可能有不同的API
    if (text.length <= maxLength) {
      return text;
    } else {
      return text.substring(0, maxLength) + '...';
    }
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Text(
          'Original Text:',
          style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
        ),
        Text(
          originalText ?? '',
          style: TextStyle(fontSize: 16),
          maxLines: 5,
          overflow: TextOverflow.ellipsis,
        ),
        SizedBox(height: 20),
        Text(
          'Precis Text:',
          style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
        ),
        Text(
          precisText ?? '',
          style: TextStyle(fontSize: 16, color: Colors.grey),
        ),
      ],
    );
  }
}

注意

  1. 上面的 generatePrecis 函数是一个简化的示例,实际使用时应该根据 precis 插件的文档调用其提供的API。
  2. 由于 precis 插件可能并不真实存在或具有不同的API,因此上述代码中的 generatePrecis 函数和插件导入路径需要根据实际使用的插件进行调整。
  3. 如果 precis 插件确实存在且功能丰富,它可能提供了更复杂的文本摘要算法,而不仅仅是简单的截断。

为了获得准确的信息和使用方法,建议查阅该插件的官方文档或仓库。如果 precis 插件不存在,可以考虑使用其他文本摘要或处理库,如 text_summarization 等,这些库可能提供更高级的功能。

回到顶部